Warum erhalte ich keine Syntaxfehler, wenn ich mein Python-Skript mit Perl ausführe?

85

Ich habe gerade einige Test-Python-Codes geschrieben test.pyund starte sie wie folgt:

perl test.py

Nach einer Weile erkannte ich meinen Fehler. Ich sage "nach einer Weile", weil der Python-Code tatsächlich korrekt ausgeführt wird, wie im Python-Interpreter!

Warum interpretiert mein Perl mein Python? test.pysieht aus wie das:

#!/usr/bin/python

...Python code here...

Interessanterweise python something.plbekomme ich viele Syntaxfehler , wenn ich das Gegenteil mache (dh aufrufe ).

Dacav
quelle
6
Ich vermute, es liegt #!am Anfang der Datei. In der Tat, wenn ich den Knall entferne, bekomme ich das erwartete Verhalten. Ist das aus Sicherheitsgründen überhaupt keine schlechte Idee?
Dacav
7
Nein. Der Punkt des Shebang-Pfads, um einen Interpreter anzugeben. Wenn Sie dem Code nicht vertrauen, sollten Sie ihn gar nicht erst ausführen.
Sobrique
1
Nein nicht wirklich. Ihr Skript ist eine Textdatei. Nicht mehr und nicht weniger. Ohne Dolmetscher läuft es nicht.
Sobrique
4
"Warum interpretiert mein Perl mein Python?" ist nicht "ein Problem, das nicht mehr reproduziert werden kann oder ein einfacher Tippfehler." Zur Wiedereröffnung gewählt. Die positiven Stimmen zu Q und A zeigen, dass dies eine Frage von allgemeinem Interesse ist.
Ikegami
1
@ikegami Unabhängig von der Beliebtheit ist dies eindeutig kein "einfacher Tippfehler ... der auf eine Weise behoben wurde, die zukünftigen Lesern wahrscheinlich nicht helfen wird". Zur Wiedereröffnung gewählt.
ThisSuitIsBlackNot

Antworten:

114

Von Perlrun ,

Wenn die #!Zeile weder das Wort "perl" noch das Wort "indir" enthält, #!wird anstelle des Perl-Interpreters das nach dem benannte Programm ausgeführt. Dies ist etwas bizarr, hilft aber Menschen auf Computern, die dies nicht tun #!, da sie einem Programm mitteilen können, dass ihre SHELL / usr / bin / perl ist , und Perl das Programm dann an den richtigen Interpreter für sie sendet.

Beispielsweise,

$ cat a
#!/bin/cat
meow

$ perl a
#!/bin/cat
meow
Ikegami
quelle
32
Beeindruckend. Sprechen Sie über Ihre obskuren Funktionen. Ich benutze Perl seit mehr als 20 Jahren und hatte keine Ahnung, dass es das tat.
cjm
4
Ich habe angefangen, Perl v4 unter DOS, VMS und Solaris zu verwenden. Es sind Betriebssystemunabhängige / Bridging-Funktionen wie diese, die das plattformübergreifende Leben so viel einfacher gemacht haben.
10.
1
@MarcvanLeeuwen Wenn Sie Programme für Linux, OSX, VAX / VMS, Windows, Solaris, OS / 2 und was auch immer schreiben, ist der lästigste Teil beim Portieren eines Programms in Skriptsprache der Start, wie viele dieser Systeme jedoch normalerweise Wenn Sie die Funktion "Befehl eingeben, gefunden und ausgeführt haben" gemeinsam nutzen, können Sie fast alles andere anders ausführen. Diese Perl-Funktion macht Perl zu einer einfachen Lücke in der Funktionalität - Sie können nur einen Unb- ähnlichen Shebang schreiben, und wenn Perl vorhanden ist, funktioniert der Code, ob Perl-Code oder nicht, immer - er ist universeller #! /usr/bin/env foo.
zxq9
1
@immibis Aus dem Thread Shebang Line Parsing Mystery auf der Perl5-Porter-Mailingliste: " indirwar ein Programm, das entwickelt wurde, um andere Programme indirekt auszuführen. Ich erinnere mich, dass es besonders in bestimmten Situationen nützlich sein sollte, in denen das Betriebssystem nicht nativ bereitstellte Sie helfen viel und / oder vielleicht in Situationen, in denen der Betriebssystemkern Sie auf 32 Zeichenbefehlszeilen beschränkt hat. "
ThisSuitIsBlackNot
2
Dies festigt nur Perls Ruf als Küchenspüle der Programmiersprachen. Als interessante Beobachtung glaube ich, dass die ursprüngliche Implementierung von shebang als Shell-Feature war und erst später in den Unix-Kernel verschoben wurde. Perl enthält viele Shell-Mechanismen (z. B. Backticks zum Ersetzen der Befehlsausgabe), dies ist nur eine weitere.
Barmar