如何检查命令是否存在于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.ne​​t/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