1235 Stimmen

Sollte ich #! (shebang) in Python-Skripte einfügen und welche Form sollte es haben?

Sollte ich den Shebang in meine Python-Skripte einfügen? In welcher Form?

#!/usr/bin/env python 

o

#!/usr/local/bin/python

Sind diese auch tragbar? Welche Form wird am häufigsten verwendet?

Note : die Tornado Projekt verwendet den ganzen Kram. Auf der anderen Seite ist das Django Projekt nicht.

14voto

pepr Punkte 18988

Wenn die Antwort nicht eindeutig ist (d.h. Sie können sich nicht entscheiden, ob ja oder nein), ist das manchmal nicht so wichtig, und Sie können das Problem ignorieren, bis die Antwort feststeht. ist klar.

El #! dient nur zum Starten des Skripts. Django lädt die Quellen selbständig und verwendet sie. Es muss nie entscheiden, welcher Interpreter verwendet werden soll. Auf diese Weise kann das #! macht hier eigentlich keinen Sinn.

Wenn es sich um ein Modul handelt und es nicht als Skript verwendet werden kann, ist es im Allgemeinen nicht notwendig, die #! . Andererseits enthält eine Modulquelle oft if __name__ == '__main__': ... mit zumindest einigen trivialen Tests der Funktionalität. Dann wird die #! macht wieder Sinn.

Ein guter Grund für die Verwendung von #! ist, wenn Sie sowohl Python 2 als auch Python 3 Skripte verwenden - sie müssen von verschiedenen Python-Versionen interpretiert werden. Auf diese Weise müssen Sie sich merken, was python muss verwendet werden, wenn das Skript manuell gestartet wird (ohne die Option #! innen). Wenn Sie eine Mischung aus solchen Skripten haben, ist es eine gute Idee, die #! zu erstellen, sie ausführbar zu machen und sie als ausführbare Dateien zu starten (chmod ...).

Bei Verwendung von MS-Windows wird die #! hatte keinen Sinn - bis vor kurzem. Python 3.3 führt einen Windows Python Launcher (py.exe und pyw.exe) ein, der die #! Zeile, erkennt die installierten Versionen von Python und verwendet die richtige oder ausdrücklich gewünschte Version von Python. Da die Erweiterung mit einem Programm verknüpft werden kann, können Sie unter Windows ein ähnliches Verhalten erreichen wie mit dem execute-Flag in Unix-basierten Systemen.

13voto

Lennart Regebro Punkte 157632

Sie sollten ein Shebang hinzufügen, wenn das Skript ausführbar sein soll. Außerdem sollten Sie das Skript mit einer Installationssoftware installieren, die den shebang so verändert, dass er auf der Zielplattform korrekt funktioniert. Beispiele hierfür sind distutils und Distribute.

1 Stimmen

Sie müssen die #!-Zeile nicht nachträglich ändern. Dafür ist /usr/bin/env da. Hardcoding gegen einen bestimmten Python-Interpreter kann mehr schaden als nutzen. Es ist sehr anfällig für die Installation einer anderen Python-Version oder den Wechsel zwischen dem Python unserer Distribution und einer eigenen Python-Installation.

0 Stimmen

In Ubuntu werden die Ergebnisse von which wählt automatisch die Standardeinstellung, die von Systembefehlen usw. verwendet wird. Es handelt sich um einen allgemeinen Standard und das System steuert ihn zur richtigen Installation.

9voto

ETalbot Punkte 91

Als ich kürzlich Python 3.6.1 auf Windows 7 installierte, wurde auch der Python Launcher für Windows installiert, der die Shebang-Zeile verwalten soll. Ich stellte jedoch fest, dass der Python Launcher dies nicht tat: Die shebang-Zeile wurde ignoriert und Python 2.7.13 wurde immer verwendet (es sei denn, ich führte das Skript mit py -3 aus).

Um dies zu beheben, musste ich den Windows-Registrierungsschlüssel bearbeiten HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Python.File\shell\open\command . Dies hatte immer noch den Wert

"C:\Python27\python.exe" "%1" %*

aus meiner früheren Python 2.7-Installation. Ich änderte den Wert dieses Registrierungsschlüssels in

"C:\Windows\py.exe" "%1" %*

und die Python Launcher Shebang-Zeilenverarbeitung funktionierte wie oben beschrieben.

1 Stimmen

Aus der Beschreibung geht hervor, dass das Problem nicht darin bestand, dass der Python Launcher den ganzen Kram ignorierte. Das Problem war, dass Python Launcher wurde installiert, aber aufgrund der Systemkonfiguration nicht verwendet .

8voto

SDsolar Punkte 2089

Antwort: Nur, wenn Sie ein ausführbares Skript für die Befehlszeile erstellen wollen.

Hier ist das Verfahren:

Prüfen Sie zunächst, welche Zeichenfolge Sie verwenden müssen:

which python

Nehmen Sie die Ausgabe davon und fügen Sie sie (mit dem Shebang #!) in die erste Zeile ein.

Auf meinem System reagiert es folgendermaßen:

$which python
/usr/bin/python

So wird Ihr Paket aussehen:

#!/usr/bin/python

Nach dem Speichern läuft die Datei wie zuvor, da Python die erste Zeile als Kommentar ansieht.

python filename.py

Um es zu einem Befehl zu machen, kopieren Sie es so, dass die Erweiterung .py entfällt.

cp filename.py filename

Teilen Sie dem Dateisystem mit, dass diese Datei ausführbar sein wird:

chmod +x filename

Zum Testen verwenden Sie:

./filename

Am besten verschieben Sie es irgendwo in Ihren $PATH, damit Sie nur den Dateinamen selbst eingeben müssen.

sudo cp filename /usr/sbin

Auf diese Weise funktioniert es überall (ohne das ./ vor dem Dateinamen)

0 Stimmen

Ich bezweifle, dass dies die beste Vorgehensweise ist, und empfehle dringend die Verwendung von Die Lösung von GlassGhost .

0 Stimmen

Ich fand dies hilfreich und es funktionierte wunderbar für mich. dies war gut erklärt. Ich würde jedoch Kommentare begrüßen, die darauf hinweisen, warum dies keine optimale Vorgehensweise ist. Ich bin begierig zu lernen.

0 Stimmen

Ich fand dies ist gut erklärt als GlassGhosts' Lösung, außer Shebang-Format. Das bessere Shebang-Format ist: #!/usr/bin/env python3

8voto

Goblinhack Punkte 2483

Wenn Sie verschiedene Module installiert haben und ein bestimmtes python-Installation verwenden müssen, dann scheint shebang zunächst eingeschränkt zu sein. Allerdings, können Sie Tricks wie den folgenden anwenden, damit shebang zuerst als Shell aufgerufen wird zunächst als Shell-Skript aufzurufen und dann python zu wählen. Dies ist sehr flexibel imo:

#!/bin/sh
#
# Choose the python we need. Explanation:
# a) '''\' translates to \ in shell, and starts a python multi-line string
# b) "" strings are treated as string concat by python, shell ignores them
# c) "true" command ignores its arguments
# c) exit before the ending ''' so the shell reads no further
# d) reset set docstrings to ignore the multiline comment code
#
"true" '''\'
PREFERRED_PYTHON=/Library/Frameworks/Python.framework/Versions/2.7/bin/python
ALTERNATIVE_PYTHON=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
FALLBACK_PYTHON=python3

if [ -x $PREFERRED_PYTHON ]; then
    echo Using preferred python $PREFERRED_PYTHON
    exec $PREFERRED_PYTHON "$0" "$@"
elif [ -x $ALTERNATIVE_PYTHON ]; then
    echo Using alternative python $ALTERNATIVE_PYTHON
    exec $ALTERNATIVE_PYTHON "$0" "$@"
else
    echo Using fallback python $FALLBACK_PYTHON
    exec python3 "$0" "$@"
fi
exit 127
'''

__doc__ = """What this file does"""
print(__doc__)
import platform
print(platform.python_version())

Oder besser noch, um die Wiederverwendung von Code über mehrere Python-Skripte hinweg zu erleichtern:

#!/bin/bash
"true" '''\'; source $(cd $(dirname ${BASH_SOURCE[@]}) &>/dev/null && pwd)/select.sh; exec $CHOSEN_PYTHON "$0" "$@"; exit 127; '''

und dann select.sh hat:

PREFERRED_PYTHON=/Library/Frameworks/Python.framework/Versions/2.7/bin/python
ALTERNATIVE_PYTHON=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
FALLBACK_PYTHON=python3

if [ -x $PREFERRED_PYTHON ]; then
    CHOSEN_PYTHON=$PREFERRED_PYTHON
elif [ -x $ALTERNATIVE_PYTHON ]; then
    CHOSEN_PYTHON=$ALTERNATIVE_PYTHON
else
    CHOSEN_PYTHON=$FALLBACK_PYTHON
fi

3 Stimmen

Ich bin mir zwar nicht sicher, ob ein Polyglott wie dieser generell eine gute Praxis ist, aber es ist auf jeden Fall ein sehr interessanter Ansatz und wahrscheinlich die flexibelste Antwort in diesem Fall.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X