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


9

之前,我对which跨不同平台(Linux与Solaris vx。OS X)的命令输出有所不同感到沮丧,因为不同的外壳也可能会引起问题。 type有人建议将其作为更好的替代方法,但是它的便携性如何?

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

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

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

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

Answers:


10

在21世纪,特别是如果您针对的是可能具有bash或zsh的计算机,则可以依靠type它。(从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 

今天,您可以指望Singe UNIX规范版本2中的几乎所有内容(Fortran和SCCS之类的奇特东西除外,它们仍然是可选的)。您也可以指望版本3的大部分,但这尚未在所有地方完全实现。对版本4的支持较为粗略。如果您要阅读这些规范,我建议您阅读版本3,该版本比版本2更具可读性且不那么含糊。

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

另请参阅参考资料以获取可移植Shell编程的更多技巧。


这可能会受益于扩展,以评论使用hash和的常用技术command -v
Caleb 2014年

@Caleb对于此问题,我看不到command -vover 的好处type,我们需要的只是一个布尔结果。您指的是“使用推荐的常用技术hash”?
吉尔斯(Gillles)“所以-别再邪恶了”
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.