How can I check if a command exists in a shell script?
Try using type
:
type foobar
For example:
$ type ls
ls is aliased to `ls --color=auto'
$ type foobar
-bash: type: foobar: not found
This is preferable to which
for a few reasons:
The default
which
implementations only support the-a
option that shows all options, so you have to find an alternative version to support aliasestype
will tell you exactly what you are looking at (be it a Bash function or an alias or a proper binary).type
doesn't require a subprocesstype
cannot be masked by a binary (for example, on a Linux box, if you create a program calledwhich
which appears in path before the realwhich
, things hit the fan.type
, on the other hand, is a shell built-in (yes, a subordinate inadvertently did this once).
Five ways, 4 for bash and 1 addition for zsh:
type foobar &> /dev/null
hash foobar &> /dev/null
command -v foobar &> /dev/null
which foobar &> /dev/null
(( $+commands[foobar] ))
(zsh only)
You can put any of them to your if
clause. According to my tests (https://www.topbug.net/blog/2016/10/11/speed-test-check-the-existence-of-a-command-in-bash-and-zsh/), the 1st and 3rd method are recommended in bash and the 5th method is recommended in zsh in terms of speed.
In general, that depends on your shell, but if you use bash, zsh, ksh or sh (as provided by dash), the following should work:
if ! type "$foobar_command_name" > /dev/null; then
# install foobar here
fi
For a real installation script, you'd probably want to be sure that type
doesn't return successfully in the case when there is an alias foobar
. In bash you could do something like this:
if ! foobar_loc="$(type -p "$foobar_command_name")" || [[ -z $foobar_loc ]]; then
# install foobar here
fi
The question doesn't specify a shell, so for those using fish (friendly interactive shell):
if command -v foo > /dev/null
echo exists
else
echo does not exist
end
For basic POSIX compatibility, we use the -v
flag which is an alias for --search
or -s
.