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

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


当前回答

扩展@lhunath和@GregV的答案,下面是那些希望将该检查轻松放入if语句的人的代码:

exists()
{
  command -v "$1" >/dev/null 2>&1
}

以下是使用方法:

if exists bash; then
  echo 'Bash exists!'
else
  echo 'Your system does not have Bash'
fi

其他回答

扩展@lhunath和@GregV的答案,下面是那些希望将该检查轻松放入if语句的人的代码:

exists()
{
  command -v "$1" >/dev/null 2>&1
}

以下是使用方法:

if exists bash; then
  echo 'Bash exists!'
else
  echo 'Your system does not have Bash'
fi

如果您可以:

which programname

...

type -P programname

我的Debian服务器设置:

当多个包包含相同的名称时,我遇到了问题。

例如apache2。这就是我的解决方案:

function _apt_install() {
    apt-get install -y $1 > /dev/null
}

function _apt_install_norecommends() {
    apt-get install -y --no-install-recommends $1 > /dev/null
}
function _apt_available() {
    if [ `apt-cache search $1 | grep -o "$1" | uniq | wc -l` = "1" ]; then
        echo "Package is available : $1"
        PACKAGE_INSTALL="1"
    else
        echo "Package $1 is NOT available for install"
        echo  "We can not continue without this package..."
        echo  "Exitting now.."
        exit 0
    fi
}
function _package_install {
    _apt_available $1
    if [ "${PACKAGE_INSTALL}" = "1" ]; then
        if [ "$(dpkg-query -l $1 | tail -n1 | cut -c1-2)" = "ii" ]; then
             echo  "package is already_installed: $1"
        else
            echo  "installing package : $1, please wait.."
            _apt_install $1
            sleep 0.5
        fi
    fi
}

function _package_install_no_recommends {
    _apt_available $1
    if [ "${PACKAGE_INSTALL}" = "1" ]; then
        if [ "$(dpkg-query -l $1 | tail -n1 | cut -c1-2)" = "ii" ]; then
             echo  "package is already_installed: $1"
        else
            echo  "installing package : $1, please wait.."
            _apt_install_norecommends $1
            sleep 0.5
        fi
    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

哈希变量有一个陷阱:例如,可以在命令行中键入

one_folder/process

以执行进程。为此,one_folder的父文件夹必须位于$PATH中。但当您尝试散列此命令时,它总是会成功:

hash one_folder/process; echo $? # will always output '0'