Шебанг, указывающий на script (также имеющий shebang), фактически игнорируется
Рассмотрим следующий код:
#!/usr/bin/env python
import sys
print "Hello! I've got %r as input." % sys.stdin.read()
Это chmod +x
ed script в /usr/local/bin/my_interpreter
. И это:
#!/usr/local/bin/my_interpreter
This is intended to be passed "as is" to python script.
Является chmod +x
ed script, который пытается его использовать. Если я echo something | /usr/local/bin/my_interpreter
, он работает нормально, но как только я попытаюсь выполнить script выше, он терпит неудачу с
/Users/modchan/test_interpreter/foo.bar: line 3: This: command not found
Кажется, что foo.bar
тихо перенаправляется на bash вместо моего script. Что я делаю не так? Как это сделать?
Ответы
Ответ 1
Похоже, что для Mac OS X требуется, чтобы интерпретатор был двоичным, а не другим script. Чтобы заставить его работать, измените второй интерпретатор script на
#!/usr/bin/env /usr/local/bin/my_interpreter
Но у вас есть вторая проблема: содержимое второго script будет не переходить к stdin
его интерпретатора, но путь script будет передан как команда line, т.е.
/usr/bin/env /usr/local/bin/my_interpreter /Users/modchan/test_interpreter/foo.bar
Вы должны прочитать файл по имени sys.argv[1]
, а не от sys.stdin
.
Ответ 2
Это зависит от программного загрузчика операционной системы, в которой вы работаете, и я использую OS X из ваших тегов. Многие UNIX-подобные операционные системы требуют, чтобы интерпретатор shebang был скомпилированным исполняемым двоичным кодом, а не другим script с другим shebang.
http://en.wikipedia.org/wiki/Shebang_(Unix)
Linux поддерживал это с 2.6.27.9, но автор этой статьи предполагает, что, вероятно, не существует никакого Berkeley-Unixen (который, вероятно, будет включать 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 ...