Ab dem Python 3.7.0 veröffentlicht am 27. Juni 2018 ( https://docs.python.org/3/whatsnew/3.7.html ) können Sie Ihr gewünschtes Ergebnis auf die wirkungsvollste und gleichzeitig einfachste Weise erreichen. Diese Antwort soll Ihnen einen kurzen Überblick über die verschiedenen Möglichkeiten geben. Ausführlichere Antworten finden Sie in den anderen Antworten.
TL;DR im Jahr 2021
Der große Vorteil von os.system(...)
war seine Einfachheit. subprocess
ist besser und immer noch einfach zu bedienen, insbesondere ab Python 3.5 .
import subprocess
subprocess.run("ls -a", shell=True)
Anmerkung: Dies ist die genaue Antwort auf Ihre Frage - ein Befehl wird ausgeführt
wie in einer Muschel
Bevorzugter Weg
Wenn möglich, entfernen Sie den Shell-Overhead und führen Sie den Befehl direkt aus (erfordert eine Liste).
import subprocess
subprocess.run(["help"])
subprocess.run(["ls", "-a"])
Programmargumente in einer Liste übergeben. Nicht einbeziehen \"
-Escaping für Argumente, die Leerzeichen enthalten.
Erweiterte Anwendungsfälle
Prüfen der Ausgabe
Der folgende Code spricht für sich selbst:
import subprocess
result = subprocess.run(["ls", "-a"], capture_output=True, text=True)
if "stackoverflow-logo.png" in result.stdout:
print("You're a fan!")
else:
print("You're not a fan?")
result.stdout
sind alle normalen Programmausgaben Ausschluss von Fehlern . Lesen Sie result.stderr
um sie zu bekommen.
capture_output=True
- schaltet die Erfassung ein. Andernfalls result.stderr
y result.stdout
wäre None
. Erhältlich bei Python 3.7 .
text=True
- ein praktisches Argument, das in Python 3.7 das die empfangenen Binärdaten in Python-Strings umwandelt, mit denen man leicht arbeiten kann.
Überprüfung des Rückgabecodes
Do
if result.returncode == 127: print("The program failed for some weird reason")
elif result.returncode == 0: print("The program succeeded")
else: print("The program failed unexpectedly")
Wenn Sie nur prüfen wollen, ob das Programm erfolgreich war (Returncode == 0) und andernfalls eine Exception auslösen wollen, gibt es eine bequemere Funktion:
result.check_returncode()
Da es sich aber um Python handelt, gibt es ein noch bequemeres Argument check
die das Gleiche automatisch für Sie tut:
result = subprocess.run(..., check=True)
stderr sollte innerhalb von stdout liegen
Vielleicht möchten Sie alle Programmausgaben in stdout haben, auch Fehler. Um dies zu erreichen, führen Sie
result = subprocess.run(..., stderr=subprocess.STDOUT)
result.stderr
wird dann None
y result.stdout
wird alles enthalten.
Verwendung von shell=False mit einer Argumentationskette
shell=False
erwartet eine Liste der Argumente. Sie können eine Argumentationskette jedoch auch selbst mit shlex aufteilen.
import subprocess
import shlex
subprocess.run(shlex.split("ls -a"))
Das war's.
Allgemeine Probleme
Die Chancen stehen gut, dass Sie gerade mit Python angefangen haben, wenn Sie auf diese Frage stoßen. Schauen wir uns einige häufige Probleme an.
FileNotFoundError: [Errno 2] Keine solche Datei oder Verzeichnis: 'ls -a': 'ls -a'
Sie führen einen Unterprozess ohne shell=True
. Entweder Sie verwenden eine Liste ( ["ls", "-a"]
) oder setzen shell=True
.
TypFehler: [...] NoneType [...]
_Stellen Sie sicher, dass Sie die capture_output=True
._
TypeError: ein bytesartiges Objekt ist erforderlich, nicht [...]
Sie erhalten immer Byte-Ergebnisse aus Ihrem Programm. Wenn Sie damit wie mit einer normalen Zeichenkette arbeiten wollen, setzen Sie text=True
.
subprocess.CalledProcessError: Der Befehl '[...]' gab einen Exit-Status ungleich Null zurück 1.
Ihr Befehl wurde nicht erfolgreich ausgeführt. Sie könnten die Returncode-Prüfung deaktivieren oder die Gültigkeit Ihres aktuellen Programms überprüfen.
TypFehler: init () hat ein unerwartetes Schlüsselwort-Argument erhalten [...]
Sie verwenden wahrscheinlich eine Python-Version, die älter als 3.7.0 ist; aktualisieren Sie sie auf die neueste verfügbare Version. Andernfalls gibt es andere Antworten in diesem Stack Overflow-Beitrag, die Ihnen ältere alternative Lösungen zeigen.
0 Stimmen
Ich verstehe das nicht, was ist falsch an
import os; os.system('pip list | grep anatome')
? Zumindest kann man damit Piping machen, wie mein Beispiel zeigt. Es ist nicht klar, wie man das mitimport subprocess; subprocess.run(["ls", "-l"])
.