Die Antwort auf diese Frage hängt von der von Ihnen verwendeten Python-Version ab. Der einfachste Ansatz ist die Verwendung der subprocess.check_output
Funktion:
>>> subprocess.check_output(['ls', '-l'])
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
check_output
führt ein einzelnes Programm aus, das nur Argumente als Eingabe verwendet. 1 Das Ergebnis wird genau so zurückgegeben, wie es gedruckt wurde stdout
. Wenn Sie Eingaben schreiben müssen, fahren Sie stdin
mit den Abschnitten run
oder fort Popen
. Wenn Sie komplexe Shell-Befehle ausführen möchten, lesen Sie den Hinweis am shell=True
Ende dieser Antwort.
Die check_output
Funktion funktioniert auf fast allen Versionen von Python, die noch weit verbreitet sind (2.7+). 2 Für neuere Versionen ist dies jedoch nicht mehr der empfohlene Ansatz.
Moderne Versionen von Python (3.5 oder höher): run
Wenn Sie Python 3.5 oder höher verwenden und keine Abwärtskompatibilität benötigen , wird die neue run
Funktion empfohlen. Es bietet eine sehr allgemeine API auf hoher Ebene für das subprocess
Modul. Übergeben Sie das subprocess.PIPE
Flag an das stdout
Schlüsselwortargument, um die Ausgabe eines Programms zu erfassen . Greifen Sie dann auf das stdout
Attribut des zurückgegebenen CompletedProcess
Objekts zu:
>>> import subprocess
>>> result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE)
>>> result.stdout
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
Der Rückgabewert ist ein bytes
Objekt. Wenn Sie also eine richtige Zeichenfolge wünschen, müssen Sie decode
diese verwenden. Angenommen, der aufgerufene Prozess gibt eine UTF-8-codierte Zeichenfolge zurück:
>>> result.stdout.decode('utf-8')
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
Dies kann alles zu einem Einzeiler komprimiert werden:
>>> subprocess.run(['ls', '-l'], stdout=subprocess.PIPE).stdout.decode('utf-8')
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
Wenn Sie Eingaben an den Prozess übergeben möchten stdin
, übergeben Sie ein bytes
Objekt an das input
Schlüsselwortargument:
>>> cmd = ['awk', 'length($0) > 5']
>>> input = 'foo\nfoofoo\n'.encode('utf-8')
>>> result = subprocess.run(cmd, stdout=subprocess.PIPE, input=input)
>>> result.stdout.decode('utf-8')
'foofoo\n'
Sie können Fehler erfassen, indem Sie stderr=subprocess.PIPE
(Capture to result.stderr
) oder stderr=subprocess.STDOUT
(Capture to result.stdout
zusammen mit der regulären Ausgabe) übergeben. Wenn die Sicherheit keine shell=True
Rolle spielt , können Sie auch komplexere Shell-Befehle ausführen, indem Sie wie in den folgenden Hinweisen beschrieben übergeben.
Dies erhöht die Komplexität im Vergleich zur alten Vorgehensweise. Aber ich denke, es lohnt sich: Jetzt können Sie fast alles tun, was Sie brauchen, um die run
Funktion alleine zu nutzen.
Ältere Versionen von Python (2.7-3.4): check_output
Wenn Sie eine ältere Version von Python verwenden oder eine bescheidene Abwärtskompatibilität benötigen, können Sie die check_output
Funktion wahrscheinlich wie oben kurz beschrieben verwenden. Es ist seit Python 2.7 verfügbar.
subprocess.check_output(*popenargs, **kwargs)
Es akzeptiert dieselben Argumente wie Popen
(siehe unten) und gibt eine Zeichenfolge zurück, die die Ausgabe des Programms enthält. Der Anfang dieser Antwort enthält ein detaillierteres Verwendungsbeispiel. In Python 3.5 und höher check_output
entspricht dies der Ausführung run
mit check=True
und stdout=PIPE
und der Rückgabe nur des stdout
Attributs.
Sie können übergeben, stderr=subprocess.STDOUT
um sicherzustellen, dass Fehlermeldungen in der zurückgegebenen Ausgabe enthalten sind. In einigen Versionen von Python kann das Übergeben stderr=subprocess.PIPE
an check_output
jedoch Deadlocks verursachen . Wenn die Sicherheit keine shell=True
Rolle spielt , können Sie auch komplexere Shell-Befehle ausführen, indem Sie wie in den folgenden Hinweisen beschrieben übergeben.
Wenn Sie stderr
Eingaben an den Prozess weiterleiten oder an diesen übergeben müssen, check_output
ist dies nicht der Aufgabe gewachsen. Siehe die folgenden Popen
Beispiele in diesem Fall.
Komplexe Anwendungen und Legacy-Versionen von Python (2.6 und niedriger): Popen
Wenn Sie eine umfassende Abwärtskompatibilität benötigen oder komplexere Funktionen als check_output
die bereitgestellten benötigen , müssen Sie direkt mit Popen
Objekten arbeiten, die die Low-Level-API für Unterprozesse kapseln.
Der Popen
Konstruktor akzeptiert entweder einen einzelnen Befehl ohne Argumente oder eine Liste mit einem Befehl als erstem Element, gefolgt von einer beliebigen Anzahl von Argumenten, die jeweils als separates Element in der Liste aufgeführt sind. shlex.split
kann helfen, Zeichenfolgen in entsprechend formatierte Listen zu analysieren. Popen
Objekte akzeptieren auch eine Vielzahl unterschiedlicher Argumente für die Prozess-E / A-Verwaltung und die Konfiguration auf niedriger Ebene.
Das Senden und Erfassen von Ausgaben communicate
ist fast immer die bevorzugte Methode. Wie in:
output = subprocess.Popen(["mycmd", "myarg"],
stdout=subprocess.PIPE).communicate()[0]
Oder
>>> import subprocess
>>> p = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE,
... stderr=subprocess.PIPE)
>>> out, err = p.communicate()
>>> print out
.
..
foo
Wenn Sie festlegen stdin=PIPE
, communicate
können Sie auch Daten an den Prozess übergeben über stdin
:
>>> cmd = ['awk', 'length($0) > 5']
>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
... stderr=subprocess.PIPE,
... stdin=subprocess.PIPE)
>>> out, err = p.communicate('foo\nfoofoo\n')
>>> print out
foofoo
Hinweis Aaron Hall Antwort , die das auf einigen Systemen gibt, können Sie festlegen müssen stdout
, stderr
und stdin
alle PIPE
(oder DEVNULL
) zu erhalten , communicate
überhaupt zu arbeiten.
In einigen seltenen Fällen benötigen Sie möglicherweise eine komplexe Ausgabeerfassung in Echtzeit. Die Antwort von Vartec schlägt einen Weg nach vorne vor, aber andere Methoden als diese communicate
neigen zu Deadlocks, wenn sie nicht sorgfältig angewendet werden.
Wie bei allen oben genannten Funktionen können Sie komplexere Shell-Befehle ausführen, wenn die Sicherheit keine Rolle spielt shell=True
.
Anmerkungen
1. Shell-Befehle ausführen: das shell=True
Argument
Normalerweise wird jeder Anruf run
, check_output
oder der Popen
Konstruktor führt ein einziges Programm . Das bedeutet, dass es keine ausgefallenen Pfeifen im Bash-Stil gibt. Wenn Sie komplexe Shell-Befehle ausführen möchten, können Sie übergeben shell=True
, was alle drei Funktionen unterstützen.
Dies wirft jedoch Sicherheitsbedenken auf . Wenn Sie mehr als nur Light Scripting ausführen, ist es möglicherweise besser, jeden Prozess einzeln aufzurufen und die Ausgabe von jedem als Eingabe an die nächste über zu übergeben
run(cmd, [stdout=etc...], input=other_output)
Oder
Popen(cmd, [stdout=etc...]).communicate(other_output)
Die Versuchung, Rohre direkt anzuschließen, ist groß; widerstehen. Andernfalls werden Sie wahrscheinlich Deadlocks sehen oder Hacky Dinge wie zu tun dies .
2. Unicode-Überlegungen
check_output
Gibt eine Zeichenfolge in Python 2 zurück, aber ein bytes
Objekt in Python 3. Es lohnt sich, sich einen Moment Zeit zu nehmen , um etwas über Unicode zu lernen, wenn Sie dies noch nicht getan haben.