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

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


当前回答

剧本

#!/bin/bash

# Commands found in the hash table are checked for existence before being
# executed and non-existence forces a normal PATH search.
shopt -s checkhash

function exists() {
 local mycomm=$1; shift || return 1

 hash $mycomm 2>/dev/null || \
 printf "\xe2\x9c\x98 [ABRT]: $mycomm: command does not exist\n"; return 1;
}
readonly -f exists

exists notacmd
exists bash
hash
bash -c 'printf "Fin.\n"'

后果

✘ [ABRT]: notacmd: command does not exist
hits    command
   0    /usr/bin/bash
Fin.

其他回答

这里有很多选择,但我很惊讶没有快速的一句话。这是我在脚本开始时使用的方法:

[[ "$(command -v mvn)" ]] || { echo "mvn is not installed" 1>&2 ; exit 1; }
[[ "$(command -v java)" ]] || { echo "java is not installed" 1>&2 ; exit 1; }

这是基于此处选择的答案和另一个来源。

为了模拟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; }

我找不到一个可行的解决方案,但编辑了一下后,我想到了这个。这对我有用:

dpkg --get-selections | grep -q linux-headers-$(uname -r)

if [ $? -eq 1 ]; then
        apt-get install linux-headers-$(uname -r)
fi

如果你想检查一个程序是否存在,是否真的是一个程序,而不是Bash内置命令,那么命令、类型和散列不适合测试,因为它们都会返回内置命令的0退出状态。

例如,时间程序提供了比时间内置命令更多的功能。要检查程序是否存在,我建议使用以下示例中的哪个:

# First check if the time program exists
timeProg=`which time`
if [ "$timeProg" = "" ]
then
  echo "The time program does not exist on this system."
  exit 1
fi

# Invoke the time program
$timeProg --quiet -o result.txt -f "%S %U + p" du -sk ~
echo "Total CPU time: `dc -f result.txt` seconds"
rm result.txt

如果你的男人/女孩不能在这里得到答案中的东西,并且你的头发从你的背部,尝试使用bash-c运行相同的命令。看看这个梦游性谵妄。这是运行$(子命令)时真正发生的情况:

第一它可以给你完全不同的输出。

$ command -v ls
alias ls='ls --color=auto'
$ bash -c "command -v ls"
/bin/ls

第二它根本不会给你任何输出。

$ command -v nvm
nvm
$ bash -c "command -v nvm"
$ bash -c "nvm --help"
bash: nvm: command not found