Woher #!/usr/bin/env python
weiß das System, wenn ich mit dem shebang ein Skript ausführe, welches python
zu verwenden ist? Wenn ich python
in den Umgebungsvariablen nach einem bin-Pfad suche, finde ich nichts.
env | grep -i python
Woher #!/usr/bin/env python
weiß das System, wenn ich mit dem shebang ein Skript ausführe, welches python
zu verwenden ist? Wenn ich python
in den Umgebungsvariablen nach einem bin-Pfad suche, finde ich nichts.
env | grep -i python
Antworten:
Der Shebang erwartet, dass ein vollständiger Pfad zum Interpreter verwendet wird, sodass die folgende Syntax falsch wäre:
So kann ein vollständiger Pfad festgelegt werden:
aber wäre nicht tragbar als Python könnte installiert
/bin
,/opt/python/bin
anderen Ort, oder wo auch immer.Verwenden
env
ist eine Methode, mit der auf tragbare Weise dem Betriebssystem ein vollständiger Pfad angegeben werden kann, der dem Pfad entspricht, in dem sich der Pfad
python
zuerst befindetPATH
.quelle
Die Shebang- Linie (also von "sharp bang"
#!
) wird vom Kernel verarbeitet. Der Kernel möchte nichts über Umgebungsvariablen wie wissenPATH
. Der Name in der shebang-Zeile muss also ein absoluter Pfad zu einer ausführbaren Datei sein. Sie können auch ein zusätzliches Argument angeben, das vor dem Skriptnamen an die ausführbare Datei übergeben wird (mit systemabhängigen Einschränkungen, auf die ich hier nicht eingehen werde). Beispielsweise können Sie für ein Python-Skript angebenIn der ersten Zeile und wenn Sie das Skript ausführen, wird der Kernel tatsächlich ausgeführt
/usr/bin/python /path/to/script
. Dies ist jedoch nicht bequem: Sie müssen den vollständigen Pfad des Befehls angeben. Was passiert , wenn Siepython
in/usr/bin
auf einigen Rechnern und/usr/local/bin
auf andere? Oder möchten Sie festlegenPATH
,/home/joe/opt/python-2.5/bin
dass eine bestimmte Version von Python verwendet wird? Da der Kernel diePATH
Suche nicht für Sie übernimmt , besteht die Idee darin, den Kernel dazu zu bringen, einen Befehl auszuführen, der den gewünschten Interpreter in denPATH
folgenden Abschnitten nachschlägt :Das
path-lookup-command
muss den Namen einer ausführbaren Datei als Argument nehmen und nachschlagenPATH
und ausführen: Der Kernel wird ausgeführt/fixed/path/to/path-lookup-command python /path/to/script
. Derenv
Befehl macht genau das. Der Hauptzweck besteht darin, einen Befehl in einer anderen Umgebung auszuführen. Da jedoch der Befehlsname$PATH
darin nachgeschlagen wird, ist er für unseren Zweck hier perfekt.Obwohl dies nicht offiziell garantiert ist, haben historische Unix-Systeme, die
env
in/usr/bin
und modernen Systemen bereitgestellt werden, diesen Ort genau wegen der weit verbreiteten Verwendung von beibehalten#!/usr/bin/env
. In der Praxis können Sie also festlegen, dass ein Skript vom bevorzugten Python-Interpreter des Benutzers ausgeführt werden mussquelle
env
und bevorzugtwhich
? Seitdem wird auch die am besten geeignete ausführbare Datei aus meiner PATH-Umgebung abgerufen.which
findet die ausführbare Datei und druckt ihren Pfad.env
Findet das durch das erste Argument angegebene Programm und führt es aus, wobei die restlichen Argumente übergeben werden.env
eine Evaluierungsversion von imwhich
Wesentlichen ist.Richtig, so laufen:
Ihr $ PATH ist eine Liste von Verzeichnissen. Unix durchsucht diese Verzeichnisliste der Reihe nach, bis es "python" findet.
Mit dem Befehl 'which' können Sie sehen, welches Verzeichnis gefunden wird:
quelle
sys.path
zwischen einem aktivierten env$ env python3
(['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/.local/lib/python3.4/site-packages', '/usr/lib/python3.4/site-packages', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
) und./env/bin/python3
(['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/test/env3/lib/python3.4/site-packages']
).