如何检查Shell脚本中是否存在命令? [重复]

问题描述 投票:148回答:8

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

if # Check that foobar command doesnt exist
then
    # Now install foobar
fi
shell
8个回答
230
投票

通常,这取决于您的shell,但是如果您使用bash,zsh,ksh或sh(由破折号提供),则以下命令应该起作用:

if ! type "$foobar_command_name" > /dev/null; then
  # install foobar here
fi

对于真实的安装脚本,您可能需要确保在别名为type的情况下foobar不会成功返回。在bash中,您可以执行以下操作:

if ! foobar_loc="$(type -p "$foobar_command_name")" || [[ -z $foobar_loc ]]; then
  # install foobar here
fi

34
投票

尝试使用type

type foobar

例如:

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

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

出于某些原因,它比which更可取:

  1. 默认which实现仅支持显示所有选项的-a选项,因此您必须找到支持别名的替代版本

  2. type会告诉您确切的内容(是Bash函数,别名还是适当的二进制文件。

  3. type不需要子过程

  4. type不能被二进制文件掩盖(例如,在Linux机器上,如果您创建一个名为which的程序,该程序出现在实际which之前的路径中,那么事情就扑朔迷离了。type另一方面,是内置的shell(是的,下属无意间执行了一次)。


25
投票

五种方式,bash 4种,zsh 1种:

  • 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中使用第一种方法和第三种方法,而在zsh中建议使用第五种方法。


17
投票

Check if a program exists from a Bash script很好地涵盖了这一点。在任何shell脚本中,最好不要运行command -v $command_name来测试是否可以运行$command_name。在bash中,您可以使用hash $command_name,它还会散列任何路径查找的结果,如果您只想查看二进制文件(而不是函数等),则可以使用type -P $binary_name


14
投票

问题未指定外壳,因此对于使用fish(友好的交互式外壳)的用户:

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

为了获得基本的POSIX兼容性,请使用-v标志,它是--search-s的别名。


1
投票

which <cmd>

如果适用于您的情况,也请参见options which supports以获取别名。

示例

which

PS:请注意,并非已安装的所有内容都可能在PATH中。通常,要检查是否已“安装”某些东西,将使用与操作系统相关的与安装相关的命令。例如。 [针对RHEL的$ 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. $


0
投票

我为此而在安装脚本中提供的功能

rpm -qa | grep -i "foobar"

示例通话:

function assertInstalled() {
    for var in "$@"; do
        if ! which $var &> /dev/null; then
            echo "Install $var!"
            exit 1
        fi
    done
}

0
投票

在bash和zsh中都可以使用的功能:

assertInstalled zsh vim wget python pip git cmake fc-cache

如果在# 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 } 中找不到命令,则返回非零。

© www.soinside.com 2019 - 2024. All rights reserved.