Python Subprocess Modul

Subprocess ist ein eingebautes Modul, das es uns ermöglicht, neue Systemprozesse zu starten, sich mit deren Eingabe-/Ausgabe-/Fehlerströmen zu verbinden und ihre Rückgabecodes abzurufen.

import subprocess

Ausführen eines Systembefehls

Die Funktion run wird verwendet, um einen Systembefehl auszuführen.

subprocess.run(['echo', 'Hello World!'])
Hello World!

Wenn Sie einen Befehl als einzelnen String anstelle einer Liste ausführen möchten, verwenden Sie:

subprocess.run('echo Hello World!', shell=True)
Hello World!

Beide geben die Ausgabe automatisch im Terminal aus.

WARNUNG

Vermeiden Sie `shell=True` mit nicht vertrauenswürdigen Eingaben (Risiko einer Shell-Injection).

Erfassen der Ausgabe

Um die Ausgabe zu erfassen, setzen Sie capture_output auf True:

result = subprocess.run(
  ['echo', 'Hello World!'],
  capture_output=True,
  text=True
)

output = result.stdout
error = result.stderr
returncode = result.returncode
output = "Hello World!\n"
error = ""
returncode = 0

Hier weist text=True die Funktion an, die Ausgabe als Text anstelle von Bytes zu lesen.

Ein returncode von 0 zeigt Erfolg an; jeder ungleich Null Wert zeigt einen Fehler an.

Überprüfung auf Fehler

Obwohl wir den Erfolg anhand des Rückgabecodes überprüfen können, gibt es eine pythonischere Methode, dies zu tun:

try:
  result = subprocess.run(
    ['ls', 'my_dir'],
    check=True,
  )
  print('Finished without errors.')
except subprocess.CalledProcessError:
  print('Error: Directory does not exist.')
Error: Directory does not exist.

Wenn check auf True gesetzt ist und der Rückgabecode nicht 0 ist (erfolgloser Vorgang), löst subprocess einen subprocess.CalledProcessError aus, der wie gewohnt mit einem except-Block behandelt werden kann.

Ausführen von Befehlen mit Timeout

Sie können ein Timeout für einen Prozess festlegen. Wenn es länger als die angegebene Zeit dauert, wird subprocess.TimeoutExpired ausgelöst:

try:
    subprocess.run(['sleep', '10'], timeout=5)
except subprocess.TimeoutExpired:
    print('Process took too long!')
Process took too long!

Schreiben der Ausgabe in eine Datei

Sie können die Ausgabe in eine Datei umleiten, indem Sie stdout (und stderr, falls erforderlich) auf ein Datei-Objekt setzen:

with open('output.txt', 'w') as f:
    subprocess.run(['ls', '-l'], stdout=f, stderr=f)

Hier erscheinen sowohl die normale Ausgabe als auch Fehler in der Datei, in der Reihenfolge, in der sie generiert werden.

Hinweis: text=True ist hilfreich, wenn Sie die Ausgabe als String in Python bearbeiten möchten. Es ist nicht unbedingt erforderlich, wenn die Ausgabe direkt in eine Datei umgeleitet wird.