指向脚本的shebang(也具有shebang)实际上被忽略。

27

考虑以下代码:

#!/usr/bin/env python

import sys

print "Hello! I've got %r as input." % sys.stdin.read()

这是在/usr/local/bin/my_interpreterchmod +x的脚本。还有这个:
#!/usr/local/bin/my_interpreter

This is intended to be passed "as is" to python script.

这是一个使用了 chmod +x 命令的脚本,试图利用它。如果我执行命令 echo something | /usr/local/bin/my_interpreter,它可以正常工作,但是一旦我尝试执行上述脚本,就会失败并显示以下错误:

/Users/modchan/test_interpreter/foo.bar: line 3: This: command not found

看起来 foo.bar 悄悄地被重定向到 bash,而不是我的脚本。我做错了什么?如何使其工作?


1
与 http://unix.stackexchange.com/a/20895 相比较 - moodywoody
@moodywoody,我觉得这两个问题并不相同,但是你链接的那个问题非常有用。 - toriningen
我并不是想说这个问题是重复的,只是另一个线程很有参考价值。 - moodywoody
2个回答

21

看起来 Mac OS X 要求解释器是二进制的,而不是另一个脚本。要使其工作,请将第二个脚本的解释器更改为

#!/usr/bin/env /usr/local/bin/my_interpreter

但你还有第二个问题:第二个脚本的内容不会传递到其解释器的stdin中,而是脚本路径名将作为命令行参数传递,即:

/usr/bin/env /usr/local/bin/my_interpreter /Users/modchan/test_interpreter/foo.bar

您应该通过文件名 sys.argv[1] 读取文件,而不是从 sys.stdin 中读取。


2
谢谢,在你回答之前,我已经尝试使用/usr/bin/env my_interpreter,但不知道文件名应该放在argv而不是stdin中。 - toriningen

6
这取决于您正在运行的操作系统的程序加载器,从您的标签中推断出您正在使用的是OS X。许多类UNIX操作系统需要shebang解释器是已编译的可执行二进制文件,而不是另一个带有另一个shebang的脚本。http://en.wikipedia.org/wiki/Shebang_(Unix)
Linux自2.6.27.9开始支持此功能,但本文作者建议可能没有任何伯克利衍生的Unix(这可能包括OS X)支持此功能:http://www.in-ulm.de/~mascheck/various/shebang/#interpreter-script 实现您所需的一种方法是像这样:
$!/bin/sh
exec /usr/local/bin/my_interpreter <<EOM

... content to be executed ...
EOM

另一种方式可能是这样的:

另一种方法可能是这样的:

$!/usr/bin/env /usr/local/bin/my_interpreter
... content to be executed ...

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