Ich habe ein Python-Skript, das mit einer bestimmten Python-Installation ausgeführt werden muss. Gibt es eine Möglichkeit, einen Shebang zu basteln, mit dem er läuft $FOO/bar/MyCustomPython
?
Ich habe ein Python-Skript, das mit einer bestimmten Python-Installation ausgeführt werden muss. Gibt es eine Möglichkeit, einen Shebang zu basteln, mit dem er läuft $FOO/bar/MyCustomPython
?
Antworten:
Die Shebang-Linie ist sehr begrenzt. Unter vielen Unix-Varianten (einschließlich Linux) können Sie nur zwei Wörter haben: einen Befehl und ein einziges Argument. Oft gibt es auch eine Längenbeschränkung.
Die allgemeine Lösung besteht darin, einen kleinen Shell-Wrapper zu schreiben. Nennen Sie das Python-Skript foo.py
, setzen Sie das Shell-Skript neben foo.py
und rufen Sie es auf foo
. Für diesen Ansatz ist kein bestimmter Header im Python-Skript erforderlich.
#!/bin/sh
exec "$FOO/bar/MyCustomPython" "$0.py" "$@"
Ein weiterer verlockender Ansatz besteht darin, ein Wrapper-Skript wie das oben beschriebene zu schreiben und es #!/path/to/wrapper/script
als Shebang-Zeile in das Python-Skript einzufügen. Die meisten Unices unterstützen jedoch keine Verkettung von Shebang-Skripten, sodass dies nicht funktioniert.
Wenn in MyCustomPython
war $PATH
, können Sie es verwenden env
, um nachzuschlagen:
#!/usr/bin/env MyCustomPython
import …
Ein weiterer Ansatz besteht darin, dafür zu sorgen, dass das Skript sowohl ein gültiges Shell-Skript (das den richtigen Python-Interpreter auf sich selbst lädt) als auch ein gültiges Skript in der Zielsprache (hier Python) ist. Dies setzt voraus, dass Sie einen Weg finden, ein solches zweisprachiges Skript für Ihre Zielsprache zu schreiben. In Perl ist dies bekannt als if $running_under_some_shell
.
#!/bin/sh
eval 'exec "$FOO/bar/MyCustomPerl" -wS $0 ${1+"$@"}'
if $running_under_some_shell;
use …
Hier ist eine Möglichkeit, den gleichen Effekt in Python zu erzielen. In der Shell "true"
befindet sich das true
Dienstprogramm, das seine Argumente (zwei Zeichenfolgen :
und '
) ignoriert und einen wahren Wert zurückgibt. Ist in Python "true"
eine Zeichenfolge, die wahr ist, wenn sie als Boolescher Wert interpretiert wird. Dies ist also eine if
Anweisung, die immer wahr ist und ein Zeichenfolgenliteral ausführt.
#!/bin/sh
if "true" : '''\'
then
exec "$FOO/bar/MyCustomPython" "$0" "$@"
exit 127
fi
'''
import …
Rosetta-Code verfügt über solche zweisprachigen Skripte in mehreren anderen Sprachen.
PYTHONPATH
Variable env bearbeitet , um Module von einem nicht standardmäßigen Speicherort für ein CGI-Skript auf einem System zu laden, auf das ich keinen Root-Zugriff hatte. Lebensretter. Danke noch einmal.
Shebang-Zeilen werden nicht variabel erweitert. Sie können sie daher nicht verwenden, $FOO/MyCustomPython
da sie nach einer ausführbaren Datei mit dem Namen dollar-FOO -... suchen würden.
Alternativ können Sie Ihren shebang-Punkt auf ein Shell-Skript als Interpreter setzen. Dieses Shell-Skript kann dann Umgebungsvariablen verwenden, um das richtige zu finden und es auszuführen.
Beispiel: Erstellen Sie ein mypython.sh
Skript in /usr/local/bin
(oder einem anderen Verzeichnis in Ihrem $PATH
) mit folgendem Inhalt:
#! /bin/sh
PYTHON="$FOO/bar/MyCustomPython"
exec "$PYTHON" "$@"
Dann können Sie diese Shebang-Zeile verwenden, um ein Python-Skript auszuführen MyCustomPython
über mypython.sh
:
#!/usr/bin/env mypython.sh
$python
, nicht $PYTHON
- vereinbarungs profitieren wir von Umgebungsvariablen (PAGER, REDAKTION, SHELL ... $PYTHON
in Ihrem Skript ist nicht eine Umgebungsvariable) und interne Shell - Variablen (BASH_VERSION, RANDOM, ...). Alle anderen Variablennamen sollten mindestens einen Kleinbuchstaben enthalten. Diese Konvention vermeidet das versehentliche Überschreiben von Umgebungsvariablen und internen Variablen. Verwenden Sie auch keine Erweiterungen für Ihre Skripte. Skripte definieren neue Befehle, die Sie ausführen können, und Befehle erhalten im Allgemeinen keine Erweiterungen.
Sie können entweder den absoluten Pfad zur benutzerdefinierten Python-Installation verwenden oder ihn in your $PATH
and use einfügen #!/usr/bin/env [command]
. Schreiben Sie andernfalls einen Wrapper dafür und exec
ersetzen Sie das Prozessabbild anhand des folgenden Beispiels:
#!/bin/bash
exec "$ENV/python" "$@"
Stellen Sie zunächst fest, inwiefern sich Ihre Python-Version von der bereits installierten Standard-Python-Version unterscheidet (z. B. ein zusätzliches Modul), und ändern Sie dann beim Starten des Programms den Python-Namen:
#!/usr/bin/python
import os
import sys
try:
import MyCustomModule
except ImportError:
# only need to use expandvar if you know the string below has an envvar
custprog = os.path.expandvar("$FOO/bar/MyCustomPython")
os.execv(custprog, sys.argv) # call alternate python with the same arguments
raise SystemExit('could not call %s' % custprog)
# if we get here, then we have the correct python interpreter
Dadurch sollte das Programm von jeder anderen Instanz von Python aufgerufen werden können. Ich mache etwas Ähnliches für eine Instanz mit integrierter SQL-Bibliothek, die nicht als Modul in den Python des Systems importiert werden kann.
Wenn Sie ersetzen können $FOO
in $FOO/bar/MyCustomPython
mit Betonweg Optionen können Sie die sagen env
shebang Linie , wo Ihre benutzerdefinierte Python - Version zu sehen , indem direkt eine benutzerdefinierte Einstellung PATH
in ihm.
#!/usr/bin/env PATH="/path1/to/MyCustomPython:/path2/to/MyCustomPython" python
Bearbeiten : Scheint nur ohne Anführungszeichen um die PATH-Wertzuweisung zu funktionieren:
#!/usr/bin/env PATH=/path1/to/MyCustomPython:/path2/to/MyCustomPython python
PATH
:PATH=$PATH:/path/to/whatever...