Ich bin in einer interessanten Situation, in der ich ein Python-Skript habe, das theoretisch von einer Vielzahl von Benutzern mit einer Vielzahl von Umgebungen (und PATHs) und auf einer Vielzahl von Linux-Systemen ausgeführt werden kann. Ich möchte, dass dieses Skript auf so vielen von ihnen wie möglich ohne künstliche Einschränkungen ausführbar ist. Hier sind einige bekannte Setups:
- Python 2.6 ist die System-Python-Version, daher existieren Python, Python2 und Python2.6 alle in / usr / bin (und sind äquivalent).
- Python 2.6 ist die System-Python-Version wie oben, aber Python 2.7 wird als Python2.7 daneben installiert.
- Python 2.4 ist die System-Python-Version, die mein Skript nicht unterstützt. In / usr / bin haben wir Python, Python2 und Python2.4, die äquivalent sind, und Python2.5, die das Skript unterstützt.
Ich möchte auf allen drei das gleiche ausführbare Python-Skript ausführen. Es wäre schön, wenn es zuerst versuchen würde, /usr/bin/python2.7 zu verwenden, wenn es existiert, dann auf /usr/bin/python2.6 zurückgreifen und dann auf /usr/bin/python2.5 zurückgreifen Einfach Fehler raus, wenn keiner von denen anwesend war. Ich bin jedoch nicht zu sehr damit beschäftigt, das neueste 2.x zu verwenden, solange es in der Lage ist, einen der richtigen Interpreten zu finden, falls vorhanden.
Meine erste Neigung war es, die Shebang-Linie zu ändern von:
#!/usr/bin/python
zu
#!/usr/bin/python2.[5-7]
da dies gut in bash funktioniert. Das Ausführen des Skripts bietet jedoch Folgendes:
/usr/bin/python2.[5-7]: bad interpreter: No such file or directory
Okay, also versuche ich folgendes, was auch in bash funktioniert:
#!/bin/bash -c /usr/bin/python2.[5-7]
Aber auch dies schlägt fehl mit:
/bin/bash: - : invalid option
Okay, natürlich könnte ich einfach ein separates Shell-Skript schreiben, das den richtigen Interpreter findet und das Python-Skript mit dem gefundenen Interpreter ausführt. Ich finde es einfach mühsam, zwei Dateien zu verteilen, von denen eine ausreichen sollte, solange der aktuellste Python 2-Interpreter installiert ist. Das explizite Aufrufen des Interpreters (z. B. $ python2.5 script.py
) ist keine Option. Es ist auch keine Option, sich darauf zu verlassen, dass der PATH des Benutzers auf eine bestimmte Weise eingerichtet wurde.
Bearbeiten:
Die Versionsprüfung innerhalb des Python-Skripts funktioniert nicht , da ich die "with" -Anweisung verwende, die ab Python 2.6 existiert (und in 2.5 mit verwendet werden kann from __future__ import with_statement
). Dies führt dazu, dass das Skript mit einem benutzerunfreundlichen SyntaxError sofort fehlschlägt, und verhindert, dass ich jemals die Möglichkeit habe, die Version zuerst zu überprüfen und einen entsprechenden Fehler zu melden.
Beispiel: (versuchen Sie dies mit einem Python-Interpreter unter 2.6)
#!/usr/bin/env python
import sys
print "You'll never see this!"
sys.exit()
with open('/dev/null', 'w') as out:
out.write('something')
./script.py
würde das direkte Ausführen des Skripts (dh ) dazu führen, dass Python 2.4 ausgeführt wird, wodurch Ihr Code erkennt, dass es sich um die falsche Version handelt (und möglicherweise beendet wird). Aber es gibt ein perfektes Python2.5, das stattdessen als Interpreter hätte verwendet werden können!
exec
Sie andernfalls einen Fehler aus.
execve
). Die Argumente sind Zeichenfolgenliterale, keine Globen, keine regulären Ausdrücke. Das ist es. Selbst wenn das erste Argument "/ bin / bash" und die zweiten Optionen ("-c ...") sind, werden diese Optionen nicht von einer Shell analysiert. Sie werden unbehandelt an die ausführbare Bash-Datei übergeben, weshalb Sie diese Fehler erhalten. Außerdem funktioniert der Shebang nur, wenn er am Anfang steht. Ich fürchte, Sie haben hier kein Glück (es fehlt ein Skript, das einen Python-Interpreter findet und ihm ein HIER-Dokument zuführt, das wie ein schreckliches Durcheinander klingt).
import sys; sys.version_info()
jedoch überprüfen, ob der Benutzer die erforderliche Python-Version hat.