HOWTO · Python
Wie man einen Bash-Befehl in Python ausführt
Dieses Tutorial zeigt, wie Sie Bash-Befehle in Python ausführen, mit Schwerpunkt auf Git-Befehlen. Lernen Sie die besten Methoden, einschließlich subprocess und os.system, um Befehle effektiv auszuführen. Verbessern Sie Ihren Arbeitsablauf mit praktischen Beispielen und klaren Erklärungen. Perfekt für Entwickler, die Aufgaben automatisieren und ihre Prozesse optimieren möchten.
Auf dieser Seite
Python kann Befehlszeilenprogramme und Shell-Befehle für Aufgaben wie das Erstellen von Verzeichnissen oder die Verwendung von Git starten. Für Befehle, die zu Ende laufen, ist subprocess.run() in der Regel der beste Ausgangspunkt: Es kann Ausgabe und Fehler erfassen und liefert einen Rückgabecode. Verwenden Sie os.system() für einfache Fälle, in denen keine erfasste Ausgabe benötigt wird, und wählen Sie subprocess.Popen(), wenn Sie mit einem Prozess interagieren müssen, während er läuft.
Einen Befehl mit subprocess.run() ausführen
Übergeben Sie eine Folge von Argumenten, um ein ausführbares Programm direkt aufzurufen. Dadurch vermeiden Sie, dass eine Shell den Befehl parsen muss. Das Beispiel verwendet den laufenden Python-Interpreter, hängt also weder von einer installierten Git-Version noch von einer bestimmten Shell ab.
import subprocess
import sys
result = subprocess.run(
[sys.executable, "-c", "print('Hello from Python')"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
print("stdout:", result.stdout)
print("stderr:", result.stderr)
print("return code:", result.returncode)
stdout: b'Hello from Python\n'
stderr: b''
return code: 0
stdout und stderr sind hier Bytes, und returncode ist eine ganze Zahl. Ein Rückgabecode von 0 steht üblicherweise für Erfolg; ein Wert ungleich null signalisiert, dass das Programm ein Problem gemeldet hat. Sie können ihn selbst prüfen oder check=True übergeben, damit run() bei einem Rückgabecode ungleich null eine CalledProcessError auslöst. Um beispielsweise Git auszuführen, übergeben Sie eine Argumentliste wie ['git', 'status']; seine Ausgabe hängt vom Repository ab und sollte als Daten behandelt werden, nicht als Inhalt mit festem Wortlaut angenommen werden.
Ein Programmaufruf ist nicht automatisch ein Bash-Befehl. Shell-Syntax wie Pipes, Umleitungen oder && erfordert eine Shell. Mit shell=True weisen Sie Python an, die Shell der Plattform zu verwenden; das garantiert nicht Bash. Vermeiden Sie es, nicht vertrauenswürdige Eingaben in einen Shell-Befehl zu interpolieren, da dies Command Injection ermöglichen kann.
Einen Shell-Befehl mit os.system() ausführen
os.system() ist eine eingeschränkte Option für einen einfachen Befehl, wenn Sie seine Ausgabe nicht erfassen oder Fehler im Detail behandeln müssen. Zum Beispiel fordert os.system("mkdir reports") die Shell der Plattform auf, den Befehl zum Erstellen des Verzeichnisses auszuführen. Der Befehl schreibt in die geerbten Konsolen-Streams. Die Funktion gibt einen Statuswert zurück, nicht die gewöhnliche Ausgabe des Befehls; die Interpretation dieses Status kann je nach Plattform variieren. Bevorzugen Sie subprocess.run(), wenn Sie erfasste Ausgabe, Fehler oder einen Rückgabecode konsistent prüfen müssen.
subprocess.Popen() für laufende Prozesse verwenden
Verwenden Sie subprocess.Popen(), wenn das Programm Eingaben oder eine andere Interaktion benötigt, bevor es endet. Es startet den Prozess und gibt Ihrem Code ein Prozessobjekt, mit dem er arbeiten kann. Setzen Sie für einen Prozess mit begrenzter Ausgabe stdout=subprocess.PIPE und stderr=subprocess.PIPE und rufen Sie dann communicate() auf, um diese Streams zu lesen und auf den Abschluss zu warten. Die zurückgegebenen Stream-Werte sind Bytes, sofern Sie die Dekodierung nicht separat einrichten.
communicate() ist nützlich, wenn der Prozess enden wird und seine erfasste Ausgabe in den Speicher passt. Es ist kein Streaming-Ansatz für unbegrenzte Ausgabe. Sobald communicate() abgeschlossen ist, ist der Prozess beendet; es besteht keine Notwendigkeit, kill() oder terminate() für ihn aufzurufen. Für gewöhnliche Befehle, die einfach zu Ende laufen, bietet run() die einfachere Schnittstelle.
Die richtige Methode wählen
Verwenden Sie subprocess.run() für die meisten Befehle: Übergeben Sie eine Argumentliste, erfassen Sie bei Bedarf Streams und prüfen Sie returncode. Verwenden Sie os.system() nur, wenn ein kurzer Shell-Befehl ausreicht und seine Ausgabe sowie sein detaillierter Status unwichtig sind. Verwenden Sie Popen(), wenn Ihr Programm einen laufenden Prozess verwalten oder Daten mit ihm austauschen muss. Wählen Sie eine Shell nur, wenn der Befehl Shell-Syntax benötigt, und halten Sie nicht vertrauenswürdige Werte aus interpolierten Shell-Zeichenfolgen heraus.