检测(从脚本)是否安装了软件的最佳方法是什么?

ico*_*ast 9 bash zsh standard which

之前我一直对which不同平台(Linux 与 Solaris vx. OS X)的命令输出差异感到沮丧,不同的 shell 也可能会影响到这个问题。 type已被建议作为更好的替代方案,但它的便携性如何?

过去,我编写了一些函数来解析which我遇到的不同用例的输出并处理它们。它们可以在我使用的机器上工作,因此对于我的个人脚本来说还可以,但是对于我要发布给其他人使用的软件来说,这似乎非常不可靠。

举一个可能的例子,假设我必须从脚本中检测 bash 和 zsh 在一台机器上是否可用,然后使用 zsh 运行命令(如果存在),如果 zsh 不存在并且 bash 足够,则使用 bash版本没有特定的错误。脚本的其余大部分可能是 Bourne shell 或 Ruby 或其他任何东西,但是必须使用 zsh 或最新版本的 bash 完成这一特定的事情(AFAIK)。

我可以指望type跨平台可用吗?是否有其他替代方案which可以轻松且一致地回答是否安装了特定软件的问题?

(如果你还想给出与我给出的例子特别相关的想法,那很好,但我主要只是询问一般情况:找出特定机器上是否安装了特定东西的最可靠方法是什么? ?)

Gil*_*il' 10

在 21 世纪,特别是如果您的目标是可能有 bash 或 zsh 的机器,您可以指望type可用。(它在非常古老的 unices 中不存在,例如从 1970 年代或 1980 年代初期开始。)您不能指望它的输出意味着什么,但是如果有该名称的命令,则可以指望它返回 0 并且否则非零。

which不是标准的,在实践中也不可靠type是推荐的替代方案。whereis遭受相同的问题,which并且不太常见。whence特定于 ksh 和 zsh。

如果可能,测试命令是否存在并测试其行为是否合理会更可靠。例如,通过运行来测试是否存在合适的 bash 版本bash -c 'somecommand',例如

# Test for the `-v` operator (which appeared in bash 4.2)
if bash -c 'test -v HOME' 2>/dev/null; then …
Run Code Online (Sandbox Code Playgroud)

今天,您几乎可以依赖Singe UNIX 规范第 2 版中的所有内容(除了 Fortran 和 SCCS 之类的奇特内容,无论如何它们都是可选的)。您也可以依赖版本 3 的大部分内容,但这还没有在所有地方完全实现。版本 4支持更粗略。如果您要阅读这些规范,我建议您阅读第 3 版,它比第 2 版更具可读性且更明确。

有关如何检测系统特性的示例,请查看autoconfconfigure各种软件的脚本。

另请参阅有关可移植 shell 编程的资源以获取更多提示。