我正在编写我的第一个shell脚本。在我的脚本中,我想检查某个命令是否存在,如果不存在,安装可执行文件。如何检查该命令是否存在?

if # Check that foobar command doesnt exist
then
    # Now install foobar
fi

当前回答

试着使用type:

type foobar

例如:

$ type ls
ls is aliased to `ls --color=auto'

$ type foobar
-bash: type: foobar: not found

这是更可取的,有几个原因:

The default which implementations only support the -a option that shows all options, so you have to find an alternative version to support aliases type will tell you exactly what you are looking at (be it a Bash function or an alias or a proper binary). type doesn't require a subprocess type cannot be masked by a binary (for example, on a Linux box, if you create a program called which which appears in path before the real which, things hit the fan. type, on the other hand, is a shell built-in (yes, a subordinate inadvertently did this once).

其他回答

这个问题没有指定shell,所以对于那些使用fish(友好的交互式shell)的人:

if command -v foo > /dev/null
  echo exists
else
  echo does not exist
end

为了基本的POSIX兼容性,我们使用-v标志,它是——search或-s的别名。

试着使用type:

type foobar

例如:

$ type ls
ls is aliased to `ls --color=auto'

$ type foobar
-bash: type: foobar: not found

这是更可取的,有几个原因:

The default which implementations only support the -a option that shows all options, so you have to find an alternative version to support aliases type will tell you exactly what you are looking at (be it a Bash function or an alias or a proper binary). type doesn't require a subprocess type cannot be masked by a binary (for example, on a Linux box, if you create a program called which which appears in path before the real which, things hit the fan. type, on the other hand, is a shell built-in (yes, a subordinate inadvertently did this once).

在bash和zsh中都可以工作的函数:

# Return the first pathname in $PATH for name in $1
function cmd_path () {
  if [[ $ZSH_VERSION ]]; then
    whence -cp "$1" 2> /dev/null
  else  # bash
     type -P "$1"  # No output if not in $PATH
  fi
}

如果在$PATH中没有找到该命令,则返回非零。

而< 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" for RHEL。

5种方法,4个用于bash, 1个用于zsh:

类型foobar &> /dev/null 哈希foobar和> /dev/null 命令-v foobar和> /dev/null 哪个foobar &> /dev/null ($+突击队[foobar]) (zsh only)

你可以把它们中的任何一个放到你的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种方法。