在bash脚本中如何检查一个命令是否存在

2023-09-25 11:00:39 浏览数 (2)

问:

如何验证程序是否存在,以一种要么返回错误并退出,要么继续执行脚本的方式?

这看起来应该很容易,但它一直困扰着我。

答:

POSIX 兼容:

代码语言:javascript复制
command -v <the_command>

使用示例:

代码语言:javascript复制
if ! command -v <the_command> &> /dev/null
then
    echo "<the_command> could not be found"
    exit
fi

对于 Bash 特定环境:

代码语言:javascript复制
hash <the_command> # 用于常规命令。或
type <the_command> # 检查内置项和关键字

避免使用 which。它是一个外部进程,相对而言 hash、type 或 command 这样的内置程序执行效率更高,你还可以依靠内置程序来实际执行所需的操作,而且外部命令的效果很容易因系统而异。

  • 许多操作系统的 which 甚至不会设置退出状态,这意味着 if which foo 甚至不会正常工作,并且总是报告 foo 存在,即使它不存在(注意,一些 POSIX shell 似乎对 hash 也这样做)。
  • 许多操作系统会让 which 做一些自定义和邪恶的事情,比如更改输出,甚至 hook 到包管理器。

所以,不要使用 which,改用以下方法之一:

代码语言:javascript复制
command -v foo || { echo >&2 "I require foo but it's not installed. Aborting."; return 1; }
代码语言:javascript复制
type foo || { echo >&2 "I require foo but it's not installed. Aborting."; return 1; }

或者在文件 /etc/profile 末尾追加如下代码:

代码语言:javascript复制
which() {
  type "$@" || { echo >&2 "I require $@ , but it's not installed.  Aborting."; return 1;}
}

再重开 shell 窗口,即可替代系统原有的 which 命令。


参考:

  • stackoverflow question 592620
  • man bash

相关阅读:

  • 为什么在可执行文件或脚本名称之前需要./(点-斜杠),以便在bash中运行它
  • 在shell编程中$(cmd) 和 `cmd` 之间有什么区别

0 人点赞