4

I want to know how to check whether a command is installed.

Specifically, I want to alias vi to vim on all machines where vim is a valid command. And I want to keep my *rc files generic. But some OSes don't come with vim installed by default. And in others, vi is Vi IMproved, yet vim isn't a valid command.

I figured I could do this (bash style):

#If the version info from vi includes the phrase "Vi IMproved", then vi IS vim.
vimInfo=$(vi --version 2> /dev/null | head -n 1 | grep -Fi 'VI IMPROVED')
if [[ -z $vimInfo ]]; then
  if [[ -f $(which vim) ]]; then
    #if the value returned by 'which' is a valid directory, then vim is installed
    alias vi='vim'
  else
    #vim is not installed
    echo "Vi IMproved (vim) is not installed";
  fi
fi

But is there a better way? And is the which command guaranteed to be present on all unix-like machines?

P.S. I have *rc files for nearly every popular shell (bash, tcsh, zsh, ksh), and I intend to apply the solution in all of them. Therefore, the solution should not be shell-specific. The syntax can be, though.

Sildoreth
  • 1,884
  • 1
    Check here: http://unix.stackexchange.com/questions/10525/how-to-use-which-on-an-aliased-command – Bichoy Apr 20 '15 at 14:48
  • (http://unix.stackexchange.com/questions/10525/how-to-use-which-on-an-aliased-command) type doesn't work in tcsh. – A.B. Apr 20 '15 at 17:54

2 Answers2

3

You can use command e.g.:

command -v vim

It is a shell built-in command. (zsh, bash, ksh, but not tcsh)

In tcsh you can use this:

~> sh -c 'command -v vim'
A.B.
  • 3,442
1

I think you're overcomplicating this.

if type vim >/dev/null 2>/dev/null; then
  alias vi=vim
fi

The only reason to run vim and vi is if there are systems where these are valid commands, but the installation is somehow broken or there is another program by that name.

The type builtin exists in all POSIX shells and most Bourne shells. In csh (and only in csh), use which:

if ({ which vim }) alias vi vim >&/dev/null

In fish:

if type vim >/dev/null 2>/dev/null; alias vi=vim; end