如何验证程序是否存在,以返回错误并退出,或继续执行脚本?
看起来应该很容易,但这让我很为难。
如何验证程序是否存在,以返回错误并退出,或继续执行脚本?
看起来应该很容易,但这让我很为难。
当前回答
为了模拟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; }
其他回答
这取决于您是否想知道它是否存在于$PATH变量中的某个目录中,或者您是否知道它的绝对位置
if which programname >/dev/null; then
echo exists
else
echo does not exist
fi
否则使用
if [ -x /path/to/programname ]; then
echo exists
else
echo does not exist
fi
在第一个示例中,重定向到/dev/null/会抑制哪个程序的输出。
答复
POSIX兼容:
command -v <the_command>
示例用法:
if ! command -v <the_command> &> /dev/null
then
echo "<the_command> could not be found"
exit
fi
对于Bash特定环境:
hash <the_command> # For regular commands. Or...
type <the_command> # To check built-ins and keywords
解释
避免使用。它不仅是一个外部进程,你启动它的目的很小(这意味着像哈希、类型或命令这样的内置程序要便宜得多),你还可以依赖内置程序来实际执行你想要的操作,而外部命令的效果很容易因系统而异。
为什么要在意?
许多操作系统都有一个甚至不设置退出状态的函数,这意味着if-which foo在那里甚至不起作用,并且总是报告foo存在,即使它不存在(注意,有些POSIX shell似乎也会为hash设置)。许多操作系统都会做一些自定义和邪恶的事情,比如更改输出,甚至挂接到包管理器。
所以,不要使用哪个。请使用以下选项之一:
command -v foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed. Aborting."; exit 1; }
type foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed. Aborting."; exit 1; }
hash foo 2>/dev/null || { echo >&2 "I require foo but it's not installed. Aborting."; exit 1; }
(次要的补充说明:有些人会建议2>&-与2>/dev/null相同,但更短–这是不正确的。2>&关闭FD 2,这会在程序尝试写入stderr时导致错误,这与成功写入stderr并丢弃输出非常不同(而且很危险!))
如果你的hash bang是/bin/sh,那么你应该关心POSIX怎么说。POSIX并没有很好地定义类型和哈希的退出代码,当命令不存在时,可以看到哈希成功退出(还没有看到这种类型)。POSIX很好地定义了命令的退出状态,所以使用它可能是最安全的。
如果您的脚本使用bash,POSIX规则就不再重要了,类型和散列都变得非常安全。type现在有一个-P来搜索PATH,而hash的副作用是命令的位置将被散列(以便下次使用时更快地查找),这通常是一件好事,因为为了实际使用它,您可能会检查它的存在。
作为一个简单的例子,这里有一个函数,如果gdate存在,则运行它,否则运行date:
gnudate() {
if hash gdate 2>/dev/null; then
gdate "$@"
else
date "$@"
fi
}
具有完整功能集的替代方案
您可以使用常见的脚本来满足您的需要。
要检查是否安装了某些东西,可以执行以下操作:
checkBin <the_command> || errorMessage "This tool requires <the_command>. Install it please, and then run this tool again."
这将根据位置判断程序是否存在:
if [ -x /usr/bin/yum ]; then
echo "This is Centos"
fi
我同意lhunath不鼓励使用which,他的解决方案对Bash用户完全有效。但是,为了更便于携带,应使用命令-v:
$ command -v foo >/dev/null 2>&1 || { echo "I require foo but it's not installed. Aborting." >&2; exit 1; }
命令命令符合POSIX。参见此处了解其规范:command-execute一个简单的命令
注意:类型符合POSIX,但类型-P不符合。
#!/bin/bash
a=${apt-cache show program}
if [[ $a == 0 ]]
then
echo "the program doesn't exist"
else
echo "the program exists"
fi
#程序不是字面意思,您可以将其更改为要检查的程序名称