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:
#!python
So kann ein vollständiger Pfad festgelegt werden:
#!/usr/local/bin/python
aber wäre nicht tragbar als Python könnte installiert /bin
, /opt/python/bin
anderen Ort, oder wo auch immer.
Verwenden env
#!/usr/bin/env python
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 befindet PATH
.
Die Shebang- Linie (also von "sharp bang" #!
) wird vom Kernel verarbeitet. Der Kernel möchte nichts über Umgebungsvariablen wie wissen PATH
. 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 angeben
#!/usr/bin/python
In 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 Sie python
in /usr/bin
auf einigen Rechnern und /usr/local/bin
auf andere? Oder möchten Sie festlegen PATH
, /home/joe/opt/python-2.5/bin
dass eine bestimmte Version von Python verwendet wird? Da der Kernel die PATH
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 den PATH
folgenden Abschnitten nachschlägt :
#!/fixed/path/to/path-lookup-command python
Das path-lookup-command
muss den Namen einer ausführbaren Datei als Argument nehmen und nachschlagen PATH
und ausführen: Der Kernel wird ausgeführt /fixed/path/to/path-lookup-command python /path/to/script
. Der env
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 muss
#!/usr/bin/env python
env
und bevorzugt which
? 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 im which
Wesentlichen ist.
Richtig, so laufen:
env | grep PATH
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:
which python
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']
).