“/usr/bin/env”有什么作用?

6
< p > #! /usr/bin/env ruby#! ruby 有什么区别?

(我发现很多其他问题讨论了#! /usr/bin/env ruby#! /usr/bin/ruby之间的区别,但这不是我的问题。)


#! ruby 必须在您的路径中。因此,根据您的路径,#! ruby#!/usr/bin/ruby 可能是相同的东西。 - Jonny Henly
实际上,我刚刚以root身份进行了一个测试,其中#! ruby导致“ruby: bad interpreter: No such file or directory”...所以出于某种原因,ruby并不自然地存在于root环境中,但是/usr/bin/env可以找到它。但我认为/user/bin/env本来应该使用用户的路径... - John Bachir
1
嗯,实际上看起来 #! ruby 必须是特例,因为 #! python 不起作用,因为解释器必须是可执行文件的有效路径名 - 请参见[有关shebang的其他信息;为什么#!python不起作用?] (http://askubuntu.com/a/716281/272194)。 - Jonny Henly
2
@JohnBachir,#! ruby 失败与 ruby 是否在 root 的 PATH 中无关。在评估 shebang 时根本不会进行 PATH 查找。 - Charles Duffy
1
至少,在内核执行shebang评估时不会出现这种情况。我见过一些情况,其中shell将尝试自己处理它,但是如果您尝试在没有涉及shell解释器的情况下执行脚本(例如,使用“find . -maxdepth 1 -exec ./somescript {} +”),则可以保证您看到的行为是内核的行为,从而避免混淆因素。 - Charles Duffy
间接相关:我的回答这个问题 - Keith Thompson
1个回答

9
#! ruby

这个功能不能保证在类UNIX系统上正常工作(我所知道的任何系统都不行);一个有效的shebang必须有一个完全限定的路径。告诉你的编辑器你正在使用哪种编程语言可能足够了,但这并不意味着内核将成功使用它选择解释器来运行程序。

内核的execve系统调用不执行PATH查找——这是由C标准库包装器(如execlpexecvp)添加的,但是解析shebang是直接由内核完成的,因此你的C库细节在那里不会发生。


#!/usr/bin/env ruby

...使用PATH查找ruby可执行文件的位置。因为env可执行文件的路径已经完全指定,所以这是有效的shebang行(而#! ruby不是)。


env还有其他用途--例如,您可以运行env -i someprog以使用完全空的环境运行someprog,或者运行env FOO=bar someprog以使用环境变量FOO设置为值bar运行someprog(如果通过shell运行,则FOO=bar someprog也会这样做,但是env方法也可以在没有涉及shell的情况下工作)。

然而,在此情况下相关的用例是强制进行PATH查找。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接