How can I check if a command exists in a shell script? [duplicate]
I am writing my first shell script. In my script I would like to check if a certain command exists, and if not, install the executable. How would I check if this command exists?
if # Check that foobar command doesnt exist
then
# Now install foobar
fi
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
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.
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).
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
.
Check if a program exists from a Bash script covers this very well. In any shell script, you're best off running command -v $command_name
for testing if $command_name
can be run. In bash you can use hash $command_name
, which also hashes the result of any path lookup, or type -P $binary_name
if you only want to see binaries (not functions etc.)