So führen Sie Shell-Befehle in Python mit der Subprocess Run-Methode aus

How Execute Shell Commands Python Using Subprocess Run Method



Subprocess ist ein integriertes Python-Modul, das verwendet werden kann, um neue Prozesse zu erstellen und mit ihren Eingabe- und Ausgabedatenströmen zu interagieren. Einfacher ausgedrückt, können Sie damit Shell-Befehle ausführen und ausführbare Binärdateien ausführen, die normalerweise in verschiedenen bin-Ordnern über ein Linux-Dateisystem verstreut sind. Sie können auch einen vollständigen Pfad zu einer ausführbaren Binärdatei angeben und alle der Binärdatei zugeordneten Befehlszeilenschalter verwenden. In diesem Artikel wird erläutert, wie Sie das Subprocess-Modul und seine Run-Methode in Python-Apps verwenden. Alle Codebeispiele im Artikel wurden mit Python 3.8.2 auf Ubuntu 20.04 getestet.

Die Subprocess.run-Methode

Die Methode Subprocess.run verwendet eine Liste von Argumenten. Wenn die Methode aufgerufen wird, führt sie den Befehl aus und wartet, bis der Prozess beendet ist, und gibt am Ende ein CompletedProcess-Objekt zurück. Das CompletedProcess-Objekt gibt stdout, stderr, die beim Aufrufen der Methode verwendeten ursprünglichen Argumente und einen Rückkehrcode zurück. Stdout bezieht sich auf den vom Befehl erzeugten Datenstrom, während sich stderr auf alle Fehler bezieht, die während der Ausführung des Programms aufgetreten sind. Jeder Rückkehrcode (Exitcode) ungleich Null würde einen Fehler mit dem Befehl bedeuten, der in der Methode subprocess.run ausgeführt wird.







Beispiel 1: Ausgabeinhalt einer Textdatei mit der Methode Subprocess.run

Der folgende Befehl gibt den Inhalt einer data.txt-Datei aus, vorausgesetzt, sie enthält einen name=John-String.



importieren Teilprozess
Teilprozess.Lauf(['Katze', 'data.txt'])

Wenn Sie den obigen Code ausführen, wird die folgende Ausgabe zurückgegeben:



Name=John
AbgeschlossenerProzess(args=['Katze', 'data.txt'],Rückgabe Code=0)

Das erste Element des Listenarguments ist der Name des auszuführenden Befehls. Jedes Element in der Liste, das dem ersten Element folgt, wird als Befehlszeilenoptionen oder Schalter betrachtet. Sie können auch einzelne Bindestriche und doppelte Bindestriche verwenden, um die Optionen zu definieren. Um beispielsweise Dateien und Ordner in einem Verzeichnis aufzulisten, wäre der Code subprocess.run([ls, -l]. In den meisten Fällen können Sie jedes durch Leerzeichen getrennte Argument in einem Shell-Befehl als einzelnes Element in die an die Methode subprocess.run übergebene Liste.





Beispiel 2: Ausgabe der Subprocess.run-Methode unterdrücken

Um die Ausgabe der Methode subprocess.run zu unterdrücken, müssen Sie stdout=subprocess.DEVNULL und stderr=subprocess.DEVNULL als zusätzliche Argumente angeben.

importieren Teilprozess

Teilprozess.Lauf(['Katze', 'data.txt'],stdout=Teilprozess.DEVNULL,
stderr=Teilprozess.DEVNULL)

Das Ausführen des obigen Codes erzeugt die folgende Ausgabe:



CompletedProcess(args=['cat', 'data.txt'], returncode=0)

Beispiel 3: Ausgabe der Subprocess.run-Methode erfassen

Um die Ausgabe der Methode subprocess.run zu erfassen, verwenden Sie ein zusätzliches Argument namens capture_output=True.

importieren Teilprozess
Ausgang= Teilprozess.Lauf(['Katze', 'data.txt'],capture_output=Wahr)
drucken (Ausgang)

Das Ausführen des obigen Codes erzeugt die folgende Ausgabe:

AbgeschlossenerProzess(args=['Katze', 'data.txt'],Rückgabe Code=0,
stdout=B'name=John ',stderr=B'')

Sie können einzeln auf stdout- und stderr-Werte zugreifen, indem Sie die Methoden output.stdout und output.stderr verwenden. Die Ausgabe erfolgt als Bytefolge. Um einen String als Ausgabe zu erhalten, verwenden Sie die Methode output.stdout.decode(utf-8). Sie können auch text=True als zusätzliches Argument für den Aufruf von subprocess.run angeben, um die Ausgabe im Zeichenfolgenformat zu erhalten. Um den Exit-Statuscode abzurufen, können Sie die Methode output.returncode verwenden.

Beispiel 4: Auslösen einer Ausnahme bei einem Fehler des von der Subprocess.run-Methode ausgeführten Befehls

Um eine Ausnahme auszulösen, wenn der Befehl mit einem Status ungleich Null beendet wird, verwenden Sie das Argument check=True.

importieren Teilprozess
Teilprozess.Lauf(['Katze', 'data.tx'],capture_output=Wahr,Text=Wahr,prüfen=Wahr)

Das Ausführen des obigen Codes erzeugt die folgende Ausgabe:

Raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Befehl '['cat', 'data.tx']'
Rückgabe des Exit-Status 1 ungleich Null.

Beispiel 5: Übergeben Sie eine Zeichenfolge an einen Befehl, der von der Subprocess.run-Methode ausgeführt wird

Sie können einen String an den Befehl übergeben, der von der Methode subprocess.run ausgeführt werden soll, indem Sie das Argument input=’string’ verwenden.

importieren Teilprozess
Ausgang= Teilprozess.Lauf(['Katze'], Eingang='data.txt',capture_output=Wahr,
Text=Wahr,prüfen=Wahr)
drucken (Ausgang)

Das Ausführen des obigen Codes erzeugt die folgende Ausgabe:

CompletedProcess(args=['cat'], returncode=0, stdout='data.txt', stderr='')

Wie Sie sehen, übergibt der obige Code data.txt als String und nicht als Dateiobjekt. Um data.txt als Datei zu übergeben, verwenden Sie das stdin-Argument.

mit offen('data.txt') wieF:
Ausgang= Teilprozess.Lauf(['Katze'],stdin=F,capture_output=Wahr,
Text=Wahr,prüfen=Wahr)
drucken (Ausgang)

Das Ausführen des obigen Codes erzeugt die folgende Ausgabe:

CompletedProcess(args=['cat'], returncode=0, stdout='name=John ', stderr='')

Beispiel 6: Befehl direkt in der Shell mit der Methode Subprocess.run ausführen

Es ist möglich, einen Befehl direkt in einer Shell auszuführen, anstatt einen String-Split im Hauptbefehl und den darauffolgenden Optionen zu verwenden. Dazu müssen Sie als zusätzliches Argument shell=True übergeben. Dies wird jedoch von Python-Entwicklern abgeraten, da die Verwendung von shell=True zu Sicherheitsproblemen führen kann. Weitere Informationen zu den Auswirkungen auf die Sicherheit finden Sie unter Hier .

importieren Teilprozess
Teilprozess.Lauf('cat 'data.txt'',Hülse=Wahr)

Das Ausführen des obigen Codes erzeugt die folgende Ausgabe:

name=John

Abschluss

Die Methode subprocess.run in Python ist ziemlich mächtig, da Sie Shell-Befehle in Python selbst ausführen können. Dies hilft dabei, den gesamten Code auf Python selbst zu beschränken, ohne dass zusätzlichen Shell-Skriptcode in separaten Dateien benötigt wird. Es kann jedoch ziemlich schwierig sein, Shell-Befehle in einer Python-Liste korrekt zu tokenisieren. Sie können die Methode shlex.split() verwenden, um einfache Shell-Befehle zu tokenisieren, aber bei langen, komplexen Befehlen – insbesondere solchen mit Pipe-Symbolen – kann shlex den Befehl nicht korrekt aufteilen. In solchen Fällen kann das Debuggen ein kniffliges Problem sein. Sie können dies mit dem Argument shell=True vermeiden, aber mit dieser Aktion sind bestimmte Sicherheitsbedenken verbunden.