如何检查命令是否存在于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
对于一个真正的安装脚本,你可能想要确保在有别名foobar
的情况下这个type
不能成功返回。 在bash中你可以做这样的事情:
if ! foobar_loc="$(type -p "$foobar_command_name")" || [ -z "$foobar_loc" ]; then # install foobar here fi
尝试使用type
:
type foobar
例如:
$ type ls ls is aliased to `ls --color=auto' $ type foobar -bash: type: foobar: not found
which
以下几个原因which
这比较可取:
1)默认的实现只支持显示所有选项的-a
选项,所以你必须find一个替代版本来支持别名
2)types将告诉你到底是你在看什么(是一个bash函数或别名或适当的二进制文件)。
3)types不需要subprocess
4)types不能被二进制掩码(例如,在一个Linux机器上,如果你创build了一个程序叫做which
,那么在真正的path上出现which
,事情就是风扇type
,另一方面是shell – 是的,一个下属无意中做了一次
从Bash脚本检查一个程序是否存在,可以很好地解决这个问题。 在任何shell脚本中,最好运行command -v $command_name
来testing是否可以运行$command_name
。 在bash中,你可以使用hash $command_name
,它也可以散列任何path查找的结果,或者如果你只想看到二进制文件(不是函数等),则type -P $binary_name
。
这个问题没有指定一个shell,所以对于那些使用鱼 (友好的交互式shell)的人来说:
if command --search foo >/dev/null do echo exists else echo does not exist end
对于基本的POSIX兼容性,请使用--search
标志,这是--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
子句中。 根据我的testing( https://www.topbug.net/blog/2016/10/11/speed-test-check-the-existence-of-a-command-in-bash-and-zsh/ ),在bash中推荐使用第一种和第三种方法,在速度方面推荐在zsh中使用第五种方法。
which <cmd>
如果适用于您的情况,还可以查看支持别名的选项 。
例
$ 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中。 通常要检查是否有“安装”的东西,或者不会使用与操作系统相关的安装相关命令。 例如rpm -qa | grep -i "foobar"
rpm -qa | grep -i "foobar"
用于RHEL。
一个函数,我在一个安装脚本正是为了这个
function assertInstalled() { for var in "$@"; do if ! which $var &> /dev/null; then echo "Install $var!" exit 1 fi done }
示例调用:
assertInstalled zsh vim wget python pip git cmake fc-cache