Warum ist '#! / Usr / bin / env python' angeblich korrekter als nur '#! / Usr / bin / python'?

70

Weiß das jemand? Ich habe nie eine Antwort gefunden.

Kenneth Reitz
quelle
4
keine Tonne. Ich bin auf OSX und die Env Manpage ist dort ziemlich zweideutig.
Kenneth Reitz
16
@ S.Lott: Hast du es in letzter Zeit gelesen? Auf meiner Debian-Box ist es eine der wenig hilfreichen Manpages, die ich je gesehen habe, und das sagt etwas aus. (Hier ist die ganze "Beschreibung": Setzen Sie jeden NAME in der Umgebung auf VALUE und führen Sie COMMAND aus. Ja, das würde ihn sofort aufklären.)
Telemachus
@ Telemachos: Ja, ich habe es gelesen. Deshalb habe ich den Wikipedia-Eintrag gefunden.
S.Lott
4
Ein Problem mit env ist, dass Sie -u oder eine andere Option nicht hinzufügen können, die an die ausführbare Python-Datei übergeben werden soll
Arkady
1
Auch eine sehr gute Antwort auf eine sehr verwandte Unix SE Frage ist hier .
Albert

Antworten:

67

Wenn Sie dazu neigen, Python an verschiedenen und interessanten Stellen auf Ihrem PATH zu installieren (wie in $PATHtypischen Unix-Shells, %PATHin typischen Windows- Shells ), wird die Verwendung /usr/bin/envIhrer Laune gerecht (zumindest in Unix-ähnlichen Umgebungen), während Sie direkt zu gehen /usr/bin/pythonGewohnheit. Aber die Kontrolle darüber zu verlieren, unter welcher Python-Version Ihre Skripte ausgeführt werden, ist kein ungetrübtes Schnäppchen. Wenn Sie sich meinen Code ansehen, werden Sie eher feststellen, dass er beispielsweise #!/usr/local/bin/python2.5mit einem offenen und akzeptierenden #!/usr/bin/env pythonSkript beginnt - vorausgesetzt, das Skript ist wichtig Ich möchte sicherstellen, dass es mit der spezifischen Version ausgeführt wird, mit der ich es getestet und entwickelt habe, NICHT mit einer halbzufälligen ;-).

Alex Martelli
quelle
39
Natürlich können Sie immer #! / Usr / bin / env python2.5 verwenden, um die Menge der halbzufälligen Auswahlmöglichkeiten
einzuschränken
1
+1 Tolle Erklärung, danke! Ich war noch nie auf diese Verwendung von "env" gestoßen ... jetzt habe ich etwas zu meiner Skript-Trickkiste hinzuzufügen.
Jim Lewis
3
+1 zur Rechtfertigung, NICHT "env python" zu verwenden. Mir wurde klar, dass ich, wenn ich "env python" verwenden möchte, besser für den kleinsten gemeinsamen Nenner codieren sollte, da ich keine Kontrolle über die Python-Version hätte, die der Benutzer zuerst im PATH hat.
Glenn Jackman
15
-1 aus mehreren Gründen: / usr / local / bin ist kein Standardpfad für Python, würde nur für lokal kompilierte Installationen funktionieren ; Das Erzwingen einer Nebenversion bei shebang ist eine schlechte Idee: Möglicherweise wird vor 2.4 geschützt, aber es wird auch behauptet, dass Ihr Skript beispielsweise mit 2.6 oder 2.7 nicht kompatibel ist . Eine geringfügige Versionsbeschränkung ist eine Aufgabe für distutils / setup.py, das Paketverwaltungssystem oder bedingte Importe, nicht für shebang . Wie @Ned sagte, sollten Sie auch keine Pfade fest codieren oder verhindern, dass der Benutzer seinen Python 2.5 in ~ / bin hat, wenn das System keinen bereitstellt. Also schlechte zukunftssichere und miserable Portabilität.
MestreLion
3
#!/usr/bin/env pythonBeachten Sie auch die Tatsache, dass using und virtualenvs das Skript in der aktuellen Version ausführen! Dies kann eine gute Sache sein oder auch nicht, hängt von Ihrem Anwendungsfall ab.
Pax0r
25

Aus Wikipedia

Shebangs geben absolute Pfade zu ausführbaren Systemdateien an. Dies kann auf Systemen mit nicht standardmäßigen Dateisystemlayouts zu Problemen führen

Oft kann das Programm / usr / bin / env verwendet werden, um diese Einschränkung zu umgehen

S.Lott
quelle
10

Es findet die ausführbare Python-Datei in Ihrer Umgebung und verwendet diese. Es ist portabler, da sich Python möglicherweise nicht immer in / usr / bin / python befindet. env befindet sich immer in / usr / bin.

Charles Ma
quelle
env ist nicht immer da, aber wir erhöhen die Wahrscheinlichkeit, dass das Skript Python auf mehr Computern findet. :)
Will
5

Es findet 'Python' auch in / usr / local / bin, ~ / bin, / opt / bin, ... oder wo immer es sich versteckt.

Dirk Eddelbuettel
quelle
Vielen Dank! es verursachte tatsächlich ein Problem für mich, weil env aus irgendeinem Grund nicht existierte.
Kenneth Reitz
3
Das ist etwas irreführend. Es wird nur die erste "Python" auf Ihrem aktuellen $ PATH finden und Python-Instanzen unter OS X können sich ziemlich gut verstecken. Insbesondere die Standard-Framework-Builds von python.org und anderen haben "bin" -Unterverzeichnisse innerhalb des Frameworks, in denen "python" und andere ausführbare Dateien und Skripte gespeichert sind. Es ist sehr einfach, mehrere Instanzen zu erhalten, die an den üblichen Stellen Symlinks zu ihnen haben oder nicht, wie / usr / local / bin et al. Das Verwalten von $ PATH unter OS X ist in diesem Fall nicht so einfach wie auf Systemen ohne Builds im Framework-Stil.
Ned Deily
2
@KennethReitz: Wenn /usr/bin/envnicht vorhanden, ist Ihr System kaputt. envist ein nach POSIX-Standard erforderliches Werkzeug.
MestreLion
@MestreLion, POSIX ist keine Voraussetzung für die Ausführung von Python.
Dadinck
@KennethReitz: stimmt, aber Shebangs werden nur in POSIX-Umgebungen verwendet. Windows (und Python) ignorieren sie, daher habe ich angenommen, dass Sie sich in einer * nix-Umgebung befinden, andernfalls ist Ihre ursprüngliche Frage umstritten.
MestreLion