HOWTO · Python

Wie man einen Windows-CMD-Befehl in Python ausführt und die Ausgabe erhält

Führen Sie Windows-CMD-Befehle aus Python mit os.system() aus oder erfassen Sie die Befehlsausgabe mit Pipes über das subprocess-Modul.

Auf dieser Seite

Um einen Windows-CMD-Befehl aus Python auszuführen, verwenden Sie os.system(), wenn dessen Ausgabe lediglich in der Konsole erscheinen soll. Die Funktion gibt einen Statuswert zurück, nicht die Befehlsausgabe als Python-Zeichenkette. Soll Python die Ausgabe verarbeiten, verwenden Sie das Modul subprocess mit Pipes und communicate().

CMD-Befehle aus einem Python-Skript mit os.system() ausführen und die Ausgabe erhalten

Die Funktion os.system() übergibt einen Befehl an den Befehlsprozessor des Betriebssystems. Unter Windows ist os.system("cmd /c echo hello") ein einfaches Beispiel: CMD führt echo hello aus, und der Text erscheint in der Konsole. Der Rückgabewert der Funktion beschreibt den Status des Befehls; den angezeigten Text enthält er nicht.

Dieser Ansatz eignet sich für einen einfachen Befehl, dessen Ausgabe eine Person lesen kann. Die Beispiele verwenden die Windows-CMD-Syntax: dir, cd und md sind dort verwendete Befehlsnamen, und alle drei sind in CMD integrierte Befehle. cd kommt auch in anderen Shells vor, diese Namen sind also nicht ausschließlich Windows vorbehalten. Wenn Ihr Python-Programm das Befehlsergebnis selbst benötigt oder Standardausgabe und Standardfehler getrennt behandeln soll, verwenden Sie stattdessen subprocess.

Setzen Sie keine Befehlszeichenkette aus nicht vertrauenswürdigen Eingaben zusammen. Der Befehlsprozessor kann Shell-Metazeichen als Syntax interpretieren. Verwenden Sie mit os.system() daher nur vertrauenswürdige, fest vorgegebene Befehle.

CMD-Befehle aus einem Python-Skript mit dem Modul subprocess ausführen und die Ausgabe erhalten

Verwenden Sie subprocess.Popen(), um einen Prozess mit getrennten Pipes für Standardausgabe und Standardfehler zu starten. Der Aufruf von communicate() liest beide Datenströme und wartet, bis der Prozess beendet ist. So vermeiden Sie einen Deadlock, der auftreten kann, wenn eine Pipe voll wird, während die andere nicht gelesen wird. Die erfassten Werte sind Bytes. Dekodieren Sie sie daher vor der Verarbeitung als Text mit der vom Befehl verwendeten Zeichenkodierung.

Dieses eigenständige Beispiel verwendet unter Windows CMD und auf anderen Plattformen den aktuellen Python-Interpreter. Das Muster zum Erfassen der Ausgabe lässt sich daher auf beiden Plattformen anpassen. Es gibt die erfasste Zeile aus:

import os
import subprocess
import sys

if os.name == "nt":
    command = ["cmd", "/c", "echo", "hello"]
else:
    command = [sys.executable, "-c", "print('hello')"]

process = subprocess.Popen(
    command,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
)
stdout, stderr = process.communicate()
print(stdout.decode("utf-8").strip())
hello

Unter Windows führt cmd /c den Befehl aus und beendet sich anschließend; /k führt ihn aus, lässt den Befehlsprozessor aber geöffnet, was für ein Skript meist ungeeignet ist. Mit dem Standardwert shell=False startet Python die benannte ausführbare Datei direkt, ohne eine zusätzliche Shell zum Analysieren ihrer Argumente zu starten. Ist diese ausführbare Datei jedoch cmd, analysiert cmd seine Befehlszeile dennoch und interpretiert die CMD-Syntax; shell=False macht nicht vertrauenswürdige Werte nicht sicher. Fügen Sie niemals nicht vertrauenswürdige Eingaben in eine CMD-Befehlszeile ein. Rufen Sie eine eigenständige ausführbare Datei nach Möglichkeit direkt mit einer Argumentliste auf. Gibt der Befehl Text aus, der nicht UTF-8-kodiert ist, dekodieren Sie die erfassten Bytes mit der verwendeten Zeichenkodierung. Prüfen Sie process.returncode, wenn Ihr Programm zwischen erfolgreichem Abschluss und einem Fehler unterscheiden muss.

Weitere Details finden Sie in der Python-Dokumentation zu subprocess.