如何检查命令是否存在于shell脚本中?
我在写我的第一个shell脚本。在我的脚本中,我想检查某个命令是否存在,如果没有,请安装可执行文件。我将如何检查该命令是否存在?如何检查命令是否存在于shell脚本中?
if #check that foobar command doesnt exist
then
#now install foobar
fi
一般而言,这取决于你的shell,但如果使用(如破折号提供)的bash,zsh中和ksh或sh,以下应该工作:
if ! type "$foobar_command_name" > /dev/null; then
# install foobar here
fi
对于一个真正的安装脚本,你'd可能要确保type
在别名为foobar
的情况下不能成功返回。在bash中,你可以这样做:
if ! foobar_loc="$(type -p "$foobar_command_name")" || [ -z "$foobar_loc" ]; then
# install foobar here
fi
我喜欢这个答案。我尽量不要太受我喜欢的ivants形象的影响;) –
嗯...当我改变它说'如果!键入“foo”>/dev/null;'然后我得到屏幕上的输出“myscript.sh:line 12:type:foo:not found”,但是,它似乎仍然工作,因为当我说'如果!键入“ls”>/dev/null;'没有输出并且if语句没有被执行(因为它返回true)。当命令不存在时,我该如何静音输出? – Andrew
安德鲁,试试'如果!键入“foo”>/dev/null 2>&1;' –
尝试使用type
:
type foobar
例如:
$ type ls
ls is aliased to `ls --color=auto'
$ type foobar
-bash: type: foobar: not found
这是优选which
的几个原因:
1)的默认which
实现只支持-a
选项显示所有选项,所以你必须找到一个替代版本来支持别名。
2)类型会告诉你到底你在看什么(是一个bash函数或别名或适当的二进制文件)。
3)型不需要子
4)式不能被掩盖的二进制(例如,在Linux中,如果您创建一个名为which
程序出现在路径上的实际which
前,东西击中了风扇。type
,在另一方面,是内置在外壳[是,下属在不经意间做了这一次]
which <cmd>
也看到options which
supports的别名如果适用于你的情况。
例
$ 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:注意所安装的,不是一切都可能在PATH。通常要检查某些东西是否“安装”,或者不会使用与操作系统相关的安装相关命令。例如。用于RHEL的rpm -qa | grep -i "foobar"
。
Check if a program exists from a Bash script涵盖了这一点。在任何shell脚本中,如果可运行$command_name
,则最好使用command -v $command_name
进行测试。在bash中,你可以使用hash $command_name
,它也可以散列任何路径查找的结果,或者如果你只想查看二进制文件(不是函数等),则可以使用type -P $binary_name
。)
问题没有指定壳,因此对于使用fish (friendly interactive shell)那些:
if command --search foo >/dev/null do
echo exists
else
echo does not exist
end
对于基本POSIX的兼容性,使用-v
标志,该标志为--search
或-s
的别名。
五种方式,4 bash和1除了为zsh中:
type foobar &> /dev/null
hash foobar &> /dev/null
command -v foobar &> /dev/null
which foobar &> /dev/null
-
(($+commands[foobar]))
(zsh的只)
您可以将它们中的任何一个添加到if
子句中。根据我的测试(https://www.topbug.net/blog/2016/10/11/speed-test-check-the-existence-of-a-command-in-bash-and-zsh/),推荐在bash中使用第1种和第3种方法,在速度方面推荐在zsh中使用第5种方法。
[检查程序是否存在于Bash脚本](https://stackoverflow.com/q/592620/608639)特别建议不要使用'which'。 – jww
一个功能我在正是这种
function assertInstalled() {
for var in "[email protected]"; do
if ! which $var &> /dev/null; then
echo "Install $var!"
exit 1
fi
done
}
例如呼叫由安装脚本:
assertInstalled zsh vim wget python pip git cmake fc-cache
刚好碰到过。我认为这是相同的问题:http://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script,但它提供了更多的细节。 –
@JerryTian感谢您的链接 – Andrew
可能重复[检查程序是否存在于Bash脚本](https://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash -script) – jww