检查程序从Bash脚本存在 [英] Check if a program exists from a Bash script
问题描述
我将如何验证一个程序存在?
How would I validate that a program exists?
那么这将要么返回一个错误并退出或继续脚本?
Which would then either return an error and exit or continue with the script?
现在看来似乎应该很容易,但它已经两腿发僵我。
It seems like it should be easy, but it's been stumping me.
推荐答案
是的;避免这
。它不仅是你推出这样做很少的(意思是像散
,键入
或内建外部进程命令
是便宜的方式),您也可以依靠内建实际做你想做的,而外部命令的效果可以从系统到系统容易地改变。
Yes; avoid which
. Not only is it an external process you're launching for doing very little (meaning builtins like hash
, type
or command
are way cheaper), you can also rely on the builtins to actually do what you want, while the effects of external commands can easily vary from system to system.
为什么要照顾?
- 许多操作系统有一个
这
的甚至不设置退出状态,这意味着如果这FOO
甚至不会在那里工作,将总是报告富
存在,即使它没有(注意,一些POSIX的炮弹似乎为散
太)做到这一点。 - 许多操作系统让
这
进行定制和邪恶的东西,比如修改输出,甚至挂到包管理器。
- Many operating systems have a
which
that doesn't even set an exit status, meaning theif which foo
won't even work there and will always report thatfoo
exists, even if it doesn't (note that some POSIX shells appear to do this forhash
too). - Many operating systems make
which
do custom and evil stuff like change the output or even hook into the package manager.
所以,请不要使用这
。而是使用其中的一个:
So, don't use which
. Instead use one of these:
$ 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; }
(小边注:有些人会认为 2 - ;&安培; -
是一样的 2 - ;的/ dev / null的
但较短 - 的这是不真实的的 2 - ;&安培; -
关闭FD 2,这会导致错误的当它尝试写入到stderr方案,这是无法成功写入,并丢弃输出非常不同的(和危险!))
(Minor side-note: some will suggest 2>&-
is the same 2>/dev/null
but shorter – this is untrue. 2>&-
closes FD 2 which causes an error in the program when it tries to write to stderr, which is very different from successfully writing to it and discarding the output (and dangerous!))
如果您的哈希爆炸是 / bin / sh的
,那么你应该关心的POSIX说。 键入
和的哈希值
退出codeS并不十分顺利通过POSIX定义,散
被认为是当命令不存在成功退出(未与键入
还)。 的退出状态是深受POSIX定义的,所以,一个可能是最安全的使用。命令
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.
如果你的脚本使用庆典
不过,POSIX规则真的不重要了两者键入
和散
变成完全可以放心使用。 键入
现在有一个 -P
以仅搜索 PATH
和散
的副作用,即命令的位置将被散列(更快的查找下一次您使用它),这通常是因为你可能检查一件好事其存在为了使用它。
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.
作为一个简单的例子,这里的运行 gdate
如果它存在,否则函数日期
:
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
}
总结:
其中,庆典
是你的shell / hashbang,坚持用散
(对命令)或键入
(考虑内建&安培;关键字)。
In summary:
Where bash
is your shell/hashbang, consistently use hash
(for commands) or type
(to consider built-ins & keywords).
当编写一个脚本POSIX,使用命令-v
。
When writing a POSIX script, use command -v
.
这篇关于检查程序从Bash脚本存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!