Почему я не получаю синтаксических ошибок при выполнении сценария Python с Perl?

85

Я просто написал тестовый код на Python test.pyи запускаю его следующим образом:

perl test.py

Через некоторое время я осознал свою ошибку. Я говорю «через некоторое время», потому что код Python действительно выполняется правильно, как в интерпретаторе Python!

Почему мой Perl интерпретирует мой Python? test.pyвыглядит так:

#!/usr/bin/python

...Python code here...

Интересно, что если я сделаю обратное (то есть вызову python something.pl), я получу много синтаксических ошибок.

Дакав
источник
6
Я предполагаю, что это из-за того, что #!в начале файла. Действительно, если я уберу челку, я получу ожидаемое поведение. В любом случае, разве это не плохая идея с точки зрения безопасности?
Dacav
7
Нет. Точка пути shebang - указать интерпретатор. Если вы не доверяете запуску кода, вам вообще не следует запускать его.
Sobrique
1
Нет, не совсем. Ваш скрипт - это текстовый файл. Ни больше ни меньше. Он не будет «работать» без интерпретатора.
Sobrique
4
«Почему мой Perl интерпретирует мой Python?» это не «проблема, которую невозможно воспроизвести, или простая типографская ошибка». Проголосовали за повторное открытие. Прогнозы на Q и A показывают, что это вопрос всеобщего интереса.
ikegami
1
@ikegami Независимо от популярности, это явно не «простая типографская ошибка ... исправленная таким образом, который вряд ли поможет будущим читателям». Проголосовали за повторное открытие.
ThisSuitIsBlackNot

Ответы:

114

Из perlrun ,

Если в #!строке нет ни слова «perl», ни слова «indir», то #!вместо интерпретатора Perl выполняется программа, названная после . Это немного странно, но помогает людям на машинах, которые этого не делают #!, потому что они могут сообщить программе, что их SHELL - это / usr / bin / perl , и Perl затем отправит программу соответствующему интерпретатору для них.

Например,

$ cat a
#!/bin/cat
meow

$ perl a
#!/bin/cat
meow
икегами
источник
32
Вау. Расскажите о своих неясных чертах. Я использую Perl более 20 лет и понятия не имел, что он это делает.
cjm
4
Я начал использовать Perl v4 в DOS, VMS и Solaris. Такие независимые от ОС / мостовые функции, которые значительно упростили кроссплатформенную жизнь.
tjd
1
@MarcvanLeeuwen Когда вы пишете программы для Linux, OSX, VAX / VMS, Windows, Solaris, OS / 2 и всего остального, самая неприятная часть портирования программы на языке сценариев - это ее запуск, как и многие из этих систем, хотя обычно разделяя общую функцию «введите команду, найдет и выполнит», сделайте почти все остальное по-другому. Эта функция Perl делает Perl простым мостом в функциональности - вы можете написать просто шебанг в стиле Unix, и если Perl присутствует, код, будь то Perl-код или нет, всегда будет работать - это похоже на более универсальный #! /usr/bin/env foo.
zxq9
1
@immibis Из потока Shebang line parsing mystery в списке рассылки perl5-porters: « indirбыла программа, предназначенная для косвенного выполнения других программ. Насколько я помню, она должна была быть особенно полезной в ситуациях setuid, когда ОС изначально не обеспечивала вы сильно поможете, и / или, возможно, в ситуациях, когда ядро ​​ОС ограничивало вас 32-символьными командными строками. "
ThisSuitIsBlackNot
2
Это только укрепляет репутацию Perl как кухонной раковины языков программирования. Как интересное наблюдение, я считаю, что исходная реализация shebang была как функция оболочки, но позже она была перенесена в ядро ​​Unix. Perl включает в себя множество механизмов оболочки (например, обратные кавычки для замены вывода команд), это всего лишь один из них.
Barmar