在Linux上使用`#!/ usr / bin / env命令--argument`的Shebang行失败


53

我有一个简单的脚本:

#!/usr/bin/env ruby --verbose
# script.rb
puts "hi"

在我的OSX机器上,它运行良好:

osx% ./script.rb
hi

但是,在我的Linux机器上,它引发了一个错误

linux% ./script.rb
/usr/bin/env: ruby --verbose: No such file or directory

如果我手动运行shebang线,效果很好

linux% /usr/bin/env ruby --verbose ./script.rb
hi

但是,如果我打包ruby --verbose到一个参数中,我可以复制错误env

linux% /usr/bin/env "ruby --verbose" ./script.rb
/usr/bin/env: ruby --verbose: No such file or directory

因此,我认为这与env解释shebang线的重置有关。我正在使用GNU coreutils 8.4 env

linux% /usr/bin/env --version
env (GNU coreutils) 8.4
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Richard Mlynarik and David MacKenzie.

这似乎很奇怪。这是此版本的的常见问题env吗?还是我不知道这里发生了其他事情吗?



与coreutils 8.17相同。奇怪的。向Fedora报告,因为这明显与手册中所说的相反。
vonbrand

@vonbrand Fedora说了什么?“我们不在乎。”

Answers:


44

看起来这是因为Linux(与BSD不同)仅将一个参数传递给shebang命令(在本例中为env)。

这已在StackOverflow上进行了广泛讨论


3
另请参阅此页面,以了解不同Unices上的行为。
斯特凡Chazelas

4
规范失败。天哪。
康拉德·鲁道夫

3
如果“规范失败”是指所有Unix系统都应接受一个以上的论点,那么我100%同意您的观点:)
Alexander Mills

没有GNU那样的“ Linux”。

5

通过@rampion评论发现了这一点:

发生的是内核处理文件的前两个字符以查找#!。如果找到了这些,则它会跳过所有空格字符以寻找非空格字符,并提取解释器路径,该路径必须是真实的可执行文件,而不是另一个脚本,尽管linux对其进行了扩展以允许递归脚本处理。发现之后,它会跳到第一个非空格字符,从那里到下一个换行符,并将其作为单个参数传递给命令。没有对引号或其他元字符的“ shell”处理。这都是非常简单和蛮力的。因此,您无法在那里找到任何选择。您恰好包含了一个参数空白,内核在这里看到并传递了“ perl -w”。

资料来源:http : //lists.gnu.org/archive/html/bug-sh-utils/2002-04/msg00020.html

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.