shell中如何判断某一命令是否存在
参考:
http://www.cnblogs.com/tuzkee/p/3755230.html
https://segmentfault.com/q/1010000000156870
http://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script
避免使用which,可用下列命令实现:
$ command -v foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed. Aborting."; exit 1; }
$ type foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed. Aborting."; exit 1; }
$ hash foo 2>/dev/null || { echo >&2 "I require foo but it's not installed. Aborting."; exit 1; }
If your hash bang is /bin/sh
then you should care about what POSIX says. type
and hash
's exit codes aren't terribly well defined by POSIX, and hash
is seen to exit successfully when the command doesn't exist (haven't seen this with type
yet). command
's exit status is well defined by POSIX, so that one is probably the safest to use.
If your script uses bash
though, POSIX rules don't really matter anymore and both type
and hash
become perfectly safe to use. type
now has a -P
to search just the PATH
and hash
has the side-effect that the command's location will be hashed (for faster lookup next time you use it), which is usually a good thing since you probably check for its existence in order to actually use it.
As a simple example, here's a function that runs gdate
if it exists, otherwise date
:
gnudate() {
if hash gdate 2>/dev/null; then
gdate "$@"
else
date "$@"
fi
}
In summary:
Where bash
is your shell/hashbang, consistently use hash
(for commands) or type
(to consider built-ins & keywords).
When writing a POSIX script, use command -v
.
首先要说明的是,不要使用which来进行判断,理由如下:
1、which非SHELL的内置命令,用起来比内置命令的开销大,并且非内置命令会依赖平台的实现,不同平台的实现可能不同。
# type type type is a shell builtin # type command command is a shell builtin # type which which is hashed (/usr/bin/which)
2、很多系统的which并不设置退出时的返回值,即使要查找的命令不存在,which也返回0
# which ls /usr/bin/ls # echo $? 0 # which aaa no aaa in /usr/bin /bin /usr/sbin /sbin /usr/local/bin /usr/local/bin /usr/local/sbin /usr/ccs/bin /usr/openwin/bin /usr/dt/bin # echo $? 0
3、许多系统的which实现,都偷偷摸摸干了一些“不足为外人道也”的事情
所以,不要用which,可以使用下面的方法:
$ command -v foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed. Aborting."; exit 1; } $ type foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed. Aborting."; exit 1; } $ hash foo 2>/dev/null || { echo >&2 "I require foo but it's not installed. Aborting."; exit 1; }
犀利的原文,可以在这里查看: