如何验证程序是否存在,以返回错误并退出,或继续执行脚本?
看起来应该很容易,但这让我很为难。
如何验证程序是否存在,以返回错误并退出,或继续执行脚本?
看起来应该很容易,但这让我很为难。
当前回答
仅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'
以下是检查命令是否存在于$PATH中并可执行的便携式方法:
[ -x "$(command -v foo)" ]
例子:
if ! [ -x "$(command -v git)" ]; then
echo 'Error: git is not installed.' >&2
exit 1
fi
需要进行可执行检查,因为如果$PATH中找不到具有该名称的可执行文件,bash将返回一个不可执行文件。
还请注意,如果$PATH中存在与可执行文件同名的不可执行文件,则dash会返回前者,即使后者会被执行。这是一个bug,违反了POSIX标准。[错误报告][标准]编辑:从破折号0.5.11(Debian 11)开始,这似乎是固定的。
此外,如果要查找的命令已定义为别名,则此操作将失败。
剧本
#!/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.
这将根据位置判断程序是否存在:
if [ -x /usr/bin/yum ]; then
echo "This is Centos"
fi
我必须检查Git是否作为部署CI服务器的一部分安装。我最后的Bash脚本如下(Ubuntu服务器):
if ! builtin type -p git &>/dev/null; then
sudo apt-get -y install git-core
fi