如何检查shell脚本中是否存在命令?

时间:2011-09-22 23:34:26

标签: shell

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

if #check that foobar command doesnt exist
then
    #now install foobar
fi

8 个答案:

答案 0 :(得分:215)

一般情况下,这取决于您的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

答案 1 :(得分:32)

尝试使用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)类型不需要子进程

4)类型不能被二进制文件掩盖(例如,在linux框中,如果你创建一个名为which的程序,它出现在真实which之前的路径中,那么事情就会受到粉丝的影响。另一方面,type是一个内置的shell [是的,下属无意中曾经这样做过一次]

答案 2 :(得分:21)

五种方式,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中使用第一种和第三种方法,并且在速度方面建议在zsh中使用第五种方法。

答案 3 :(得分:16)

Check if a program exists from a Bash script非常清楚。在任何shell脚本中,如果可以运行command -v $command_name,最好运行$command_name进行测试。在bash中,你可以使用hash $command_name,它也可以使用任何路径查找的结果,或type -P $binary_name,如果你只想查看二进制文件(不是函数等)。

答案 4 :(得分:13)

问题没有指定shell,因此对于使用 fish (friendly interactive shell)的人:

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

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

答案 5 :(得分:1)

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中。通常,为了检查某些东西是否“已安装”,可以使用与OS相关的安装相关命令。例如。 RHEL rpm -qa | grep -i "foobar"

答案 6 :(得分:0)

我在安装脚本中使用的函数正好用于此

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

答案 7 :(得分:0)

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