HOWTO · Python
OSError: [Errno 8] Exec-Formatfehler in Python
In diesem Tutorial lernen Sie, OSError zu beheben: [Errno 8] Exec-Formatfehler in Python.
Auf dieser Seite
Unter Linux kann Python OSError: [Errno 8] Exec format error auslösen, wenn es das Betriebssystem auffordert, eine Datei direkt auszuführen, diese aber kein erkanntes ausführbares Format hat. Ein häufiger Fall ist ein Shell-Skript ohne Interpreterdirektive (Shebang). Dabei handelt es sich um einen Fehler beim Start durch das Betriebssystem, nicht um einen Python-Syntaxfehler. Die folgenden Beispiele verwenden das Modul subprocess und zeigen zwei Lösungen: #!/bin/sh als erste Zeile des Skripts einfügen oder sh ausdrücklich aufrufen.
Warum OSError: [Errno 8] Exec format error auftritt
Bei einem direkten Aufruf wie subprocess.run([script_path]) untersucht Linux die Zieldatei, um festzustellen, wie sie ausgeführt werden soll. Ein Skript benötigt eine gültige Shebang-Zeile, die auf einen verfügbaren Interpreter verweist; ein kompiliertes Programm braucht ein Format und eine Architektur, die das System ausführen kann. Kann Linux keinen passenden Handler für die Datei ermitteln, meldet es Python den Fehler OSError: [Errno 8] Exec format error.
Das ist von einem Berechtigungsfehler zu unterscheiden. Für die folgende Reproduktion muss das Skript ausführbar sein, damit das Betriebssystem überhaupt die Formatprüfung erreicht. Fehlt diese Berechtigung, kann der direkte Aufruf bereits vorher mit einem Berechtigungsfehler scheitern. Eine Ausführungsberechtigung allein ergänzt keine fehlende Shebang-Zeile und behebt kein nicht unterstütztes ausführbares Format.
Den Fehler mit einem Shell-Skript reproduzieren
Das folgende Linux-Beispiel erstellt ein ausführbares Shell-Skript ohne Shebang-Zeile und versucht anschließend, es direkt zu starten. Der Startfehler wird abgefangen, sodass das Beispiel regulär beendet werden kann. Prüfen Sie beim Debuggen Ihres eigenen Aufrufs den Wert von failure.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
import subprocess
import tempfile
from pathlib import Path
with tempfile.TemporaryDirectory() as directory:
script = Path(directory) / "hello.sh"
script.write_text("printf 'Hello from the script\\n'\n", encoding="utf-8")
script.chmod(0o755)
failure = None
try:
subprocess.run([str(script)], check=True, capture_output=True, text=True)
except (OSError, subprocess.CalledProcessError) as error:
failure = error
Die temporäre Datei ist ausführbar und enthält gültige Shell-Syntax, hat aber keine Interpreterdirektive in der ersten Zeile. Der genaue Fehlercode und die Meldung hängen vom Betriebssystem ab; diese Diagnose gilt für den oben beschriebenen Linux-Fall.
Dem Skript eine Shebang-Zeile hinzufügen
Setzen Sie #!/bin/sh ganz an den Anfang der Datei, noch vor alle Befehle. Bei der direkten Ausführung liest das Betriebssystem diese Interpreterdirektive aus. Sie muss in der ersten Zeile stehen. Speichern Sie die Datei als einfachen Text und stellen Sie sicher, dass /bin/sh verfügbar ist. Das Beispiel erstellt ein neues Skript mit dieser Direktive und führt es direkt aus.
Führen Sie dieses Beispiel aus:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
import subprocess
import tempfile
from pathlib import Path
with tempfile.TemporaryDirectory() as directory:
script = Path(directory) / "hello.sh"
script.write_text("#!/bin/sh\nprintf 'Hello from the script\\n'\n", encoding="utf-8")
script.chmod(0o755)
result = subprocess.run([str(script)], check=True, capture_output=True, text=True)
print(result.stdout, end="")
Hello from the script
Damit bleibt die direkte Ausführung erhalten und der Interpreter wird im Skript selbst ausdrücklich angegeben. Verwendet das Skript Funktionen, die über die POSIX-Shell hinausgehen, wählen Sie eine Shebang-Zeile für eine Shell, die diese Funktionen unterstützt und unter dem angegebenen Pfad installiert ist.
Das Skript mit einem Interpreter ausführen
Alternativ können Sie den Interpreter als auszuführendes Programm angeben und den Skriptpfad als Argument übergeben. Dabei wird die Shebang-Zeile des Skripts nicht benötigt, denn Linux startet sh direkt und sh liest die Datei ein. Das ist nützlich, wenn Sie das Skript nicht ändern können oder den Interpreter lieber beim Aufruf auswählen möchten. Der angegebene Interpreter und der Skriptpfad müssen trotzdem vorhanden sein.
Das eigenständige Beispiel unten verwendet denselben Shell-Befehl und dasselbe Muster mit einer temporären Datei.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
import subprocess
import tempfile
from pathlib import Path
with tempfile.TemporaryDirectory() as directory:
script = Path(directory) / "hello.sh"
script.write_text("printf 'Hello from the script\\n'\n", encoding="utf-8")
result = subprocess.run(["sh", str(script)], check=True, capture_output=True, text=True)
print(result.stdout, end="")
Hello from the script
Die Beispielausgabe ist die unveränderte englische Zeichenfolge „Hello from the script“.
Mit einer Argumentliste kann subprocess sh aufrufen und den Skriptpfad als einzelnes Argument übergeben. Vermeiden Sie es, aus nicht vertrauenswürdigen Eingaben eine Shell-Befehlszeichenfolge zusammenzusetzen. Eine Argumentliste hält das auszuführende Programm und seine Argumente getrennt.
Das Skript und das ausführbare Format prüfen
Mit diesen gezielten Prüfungen können Sie die Ursache des Startproblems eingrenzen:
- Prüfen Sie, ob der an
subprocessübergebene Pfad auf die gewünschte Datei verweist. Ein nicht vorhandener Pfad führt normalerweise zu einem Fehler wegen einer nicht gefundenen Datei und nicht zu einem Formatfehler bei der Ausführung. - Prüfen Sie die erste Zeile. Bei einem Shell-Skript für
/bin/shsollte sie genau#!/bin/shlauten; die Direktive muss vor allen anderen Inhalten stehen. Eine Byte-Order-Markierung oder andere Bytes davor können verhindern, dass das Betriebssystem sie als Shebang in der ersten Zeile erkennt. - Stellen Sie sicher, dass der in der Shebang-Zeile genannte Interpreter vorhanden ist und auf dem aktuellen System ausgeführt werden kann. Auch bei der Lösung mit dem ausdrücklich angegebenen Interpreter muss ein installierter Interpreter genannt werden.
- Ist das Ziel eine kompilierte ausführbare Datei, prüfen Sie, ob sie für das aktuelle Betriebssystem und die Prozessorarchitektur erstellt wurde. Erstellen Sie sie für die Zielumgebung neu oder verwenden Sie eine kompatible ausführbare Datei, wenn das Format nicht unterstützt wird.
- Behandeln Sie die Ausführungsberechtigung als separate Voraussetzung für den direkten Aufruf. Fehlt sie, beheben Sie dieses Berechtigungsproblem gesondert. Geänderte Berechtigungen beheben kein nicht erkanntes Dateiformat.
Diese Prüfungen unterscheiden ein ungültiges oder nicht erkanntes ausführbares Format von einem falschen Pfad oder einem Berechtigungsproblem. So bleibt die Lösung auf die Art abgestimmt, mit der das Skript gestartet wird.