如何验证程序是否存在,以返回错误并退出,或继续执行脚本?

看起来应该很容易,但这让我很为难。


当前回答

我必须检查Git是否作为部署CI服务器的一部分安装。我最后的Bash脚本如下(Ubuntu服务器):

if ! builtin type -p git &>/dev/null; then
  sudo apt-get -y install git-core
fi

其他回答

为了模拟Bash的-P cmd类型,我们可以使用POSIX兼容的env-i type cmd 1>/dev/null 2>&1。

man env
# "The option '-i' causes env to completely ignore the environment it inherits."
# In other words, there are no aliases or functions to be looked up by the type command.

ls() { echo 'Hello, world!'; }

ls
type ls
env -i type ls

cmd=ls
cmd=lsx
env -i type $cmd 1>/dev/null 2>&1 || { echo "$cmd not found"; exit 1; }

which命令可能有用。男子谁

如果找到可执行文件,则返回0;如果找不到或不可执行,则返回1:

NAME

       which - locate a command

SYNOPSIS

       which [-a] filename ...

DESCRIPTION

       which returns the pathnames of the files which would
       be executed in the current environment, had its
       arguments been given as commands in a strictly
       POSIX-conformant shell. It does this by searching
       the PATH for executable files matching the names
       of the arguments.

OPTIONS

       -a     print all matching pathnames of each argument

EXIT STATUS

       0      if all specified commands are 
              found and executable

       1      if one or more specified commands is nonexistent
              or not executable

       2      if an invalid option is specified

这样做的好处是,它可以确定可执行文件在运行环境中是否可用-这节省了一些问题。。。

#!/bin/bash
a=${apt-cache show program}
if [[ $a == 0 ]]
then
echo "the program doesn't exist"
else
echo "the program exists"
fi

#程序不是字面意思,您可以将其更改为要检查的程序名称

仅zsh,但对于zsh脚本非常有用(例如,在编写完成脚本时):

zsh/parameter模块可以访问内部命令哈希表等。来自man zshmodules:

THE ZSH/PARAMETER MODULE
       The zsh/parameter module gives access to some of the internal hash  ta‐
       bles used by the shell by defining some special parameters.


[...]

       commands
              This  array gives access to the command hash table. The keys are
              the names of external commands, the values are the pathnames  of
              the  files  that would be executed when the command would be in‐
              voked. Setting a key in this array defines a new entry  in  this
              table  in the same way as with the hash builtin. Unsetting a key
              as in `unset "commands[foo]"' removes the entry  for  the  given
              key from the command hash table.

尽管它是一个可加载的模块,但只要zsh不与--simulate一起使用,它似乎是默认加载的。

例子:

martin@martin ~ % echo $commands[zsh]
/usr/bin/zsh

要快速检查某个命令是否可用,只需检查哈希中是否存在密钥:

if (( ${+commands[zsh]} ))
then
  echo "zsh is available"
fi

请注意,散列将包含$PATH文件夹中的任何文件,无论它们是否可执行。为了绝对确定,您必须对此进行统计:

if (( ${+commands[zsh]} )) && [[ -x $commands[zsh] ]]
then
  echo "zsh is available"
fi

我会尝试调用程序,例如--version或--help,并检查命令是否成功或失败

与set-e一起使用时,如果找不到程序,脚本将退出,您将得到一条有意义的错误消息:

#!/bin/bash
set -e
git --version >> /dev/null