How can I check if a command exists in a shell script? [duplicate]
The community reviewed whether to reopen this question 11 months ago and left it closed:
Original close reason(s) were not resolved
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.)
A function which works in both bash and zsh:
# Return the first pathname in $PATH for name in $1
function cmd_path () {
if [[ $ZSH_VERSION ]]; then
whence -cp "$1" 2> /dev/null
else # bash
type -P "$1" # No output if not in $PATH
fi
}
Non-zero is returned if the command is not found in $PATH
.
which <cmd>
also see options which
supports for aliases if applicable to your case.
Example
$ which foobar
which: no foobar in (/usr/local/bin:/usr/bin:/cygdrive/c/Program Files (x86)/PC Connectivity Solution:/cygdrive/c/Windows/system32/System32/WindowsPowerShell/v1.0:/cygdrive/d/Program Files (x86)/Graphviz 2.28/bin:/cygdrive/d/Program Files (x86)/GNU/GnuPG
$ if [ $? -eq 0 ]; then echo "foobar is found in PATH"; else echo "foobar is NOT found in PATH, of course it does not mean it is not installed."; fi
foobar is NOT found in PATH, of course it does not mean it is not installed.
$
PS: Note that not everything that's installed may be in PATH. Usually to check whether something is "installed" or not one would use installation related commands relevant to the OS. E.g. rpm -qa | grep -i "foobar"
for RHEL.
A function I have in an install script made for exactly this
function assertInstalled() {
for var in "$@"; do
if ! which $var &> /dev/null; then
echo "Install $var!"
exit 1
fi
done
}
example call:
assertInstalled zsh vim wget python pip git cmake fc-cache
精彩评论