Woher #!/usr/bin/env pythonweiß das System, wenn ich mit dem shebang ein Skript ausführe, welches pythonzu verwenden ist? Wenn ich pythonin den Umgebungsvariablen nach einem bin-Pfad suche, finde ich nichts.
env | grep -i python
Woher #!/usr/bin/env pythonweiß das System, wenn ich mit dem shebang ein Skript ausführe, welches pythonzu verwenden ist? Wenn ich pythonin 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/binanderen 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 pythonzuerst 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 pythonin /usr/binauf einigen Rechnern und /usr/local/binauf andere? Oder möchten Sie festlegen PATH, /home/joe/opt/python-2.5/bindass eine bestimmte Version von Python verwendet wird? Da der Kernel die PATHSuche 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 PATHfolgenden Abschnitten nachschlägt :
#!/fixed/path/to/path-lookup-command python
Das path-lookup-commandmuss den Namen einer ausführbaren Datei als Argument nehmen und nachschlagen PATHund ausführen: Der Kernel wird ausgeführt /fixed/path/to/path-lookup-command python /path/to/script. Der envBefehl macht genau das. Der Hauptzweck besteht darin, einen Befehl in einer anderen Umgebung auszuführen. Da jedoch der Befehlsname $PATHdarin nachgeschlagen wird, ist er für unseren Zweck hier perfekt.
Obwohl dies nicht offiziell garantiert ist, haben historische Unix-Systeme, die envin /usr/binund 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
envund bevorzugt which? Seitdem wird auch die am besten geeignete ausführbare Datei aus meiner PATH-Umgebung abgerufen.
whichfindet die ausführbare Datei und druckt ihren Pfad. envFindet das durch das erste Argument angegebene Programm und führt es aus, wobei die restlichen Argumente übergeben werden.
enveine Evaluierungsversion von im whichWesentlichen 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.pathzwischen 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']).