Das subprocess-Modul ermöglicht es uns, einen neuen Prozess zu starten und eine Verbindung zu dessen Eingabe-/Ausgabe-/Fehler-Pipes herzustellen, wodurch wir den Rückgabewert erhalten.
Verwenden des subprocess-Moduls
Das subprocess-Modul empfiehlt zunächst die Verwendung seiner run-Methode; für fortgeschrittenere Anwendungsfälle können Sie direkt die Popen-Schnittstelle verwenden.
Die Syntax der run-Methode lautet wie folgt:
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)
- args: Gibt den auszuführenden Befehl an. Er muss eine Zeichenkette oder eine Liste von String-Parametern sein.
- stdin, stdout und stderr: Die Standardeingabe, -ausgabe und -fehler des Kindprozesses. Ihre Werte können subprocess.PIPE, subprocess.DEVNULL, ein vorhandener Dateideskriptor, ein bereits geöffnetes Dateiobjekt oder None sein. subprocess.PIPE bedeutet, eine neue Pipe für den Kindprozess zu erstellen. subprocess.DEVNULL bedeutet, os.devnull zu verwenden. Der Standardwert ist None, was bedeutet, dass nichts getan wird. Darüber hinaus kann stderr in stdout integriert werden, um gemeinsam ausgegeben zu werden.
- timeout: Legt die Timeout-Zeit für den Befehl fest. Wenn die Ausführungszeit des Befehls das Timeout überschreitet, wird der Kindprozess beendet und eine TimeoutExpired-Ausnahme ausgelöst.
- check: Wenn dieser Parameter auf True gesetzt ist und der Exit-Statuscode des Prozesses nicht 0 ist, wird eine CalledProcessError-Ausnahme ausgelöst.
- encoding: Wenn dieser Parameter angegeben wird, können stdin, stdout und stderr String-Daten empfangen und mit dieser Kodierung kodiert werden. Andernfalls werden nur Daten vom Typ bytes akzeptiert.
- shell: Wenn dieser Parameter True ist, wird der angegebene Befehl über die Shell des Betriebssystems ausgeführt.
Der Aufruf der run-Methode gibt eine CompletedProcess-Instanz zurück. Er ähnelt der direkten Verwendung von Popen; die Implementierung ist dieselbe. Tatsächlich ruft er auch Popen auf und ist ungefähr mit dem Popen-Konstruktor identisch, zum Beispiel:
Beispiel
>>> subprocess.run(["ls", "-l", "/dev/null"])
crw-rw-rw- 1 root wheel 3, 2 5 4 13:34 /dev/null
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0)
returncode: Der Status des ausgeführten Kindprozesses. Normalerweise zeigt ein Rückgabestatus von 0 an, dass er die Ausführung beendet hat. Wenn der Wert ein negativer Wert '-N' ist, zeigt dies an, dass der Kindprozess beendet wurde.
Einfaches Beispiel:
Beispiel
def runcmd(command):
ret = subprocess.run(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,encoding="utf-8",timeout=1)
if ret.returncode == 0:
print("success:",ret)
else:
print("error:",ret)
runcmd(["dir","/b"])#Sequenzargument
runcmd("exit 1")#String-Argument
Das Ausgabeergebnis ist wie folgt:
success: CompletedProcess(args=['dir', '/b'], returncode=0, stdout='test.py\n', stderr='') error: CompletedProcess(args='exit 1', returncode=1, stdout='', stderr='')
Popen()-Methode
Popen ist der Kern von subprocess; die Erstellung und Verwaltung von Kindprozessen werden von ihm übernommen.
Konstruktor:
class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0,restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None)
Gängige Parameter:
- args: Shell-Befehl, der eine Zeichenkette oder ein Sequenztyp sein kann (z. B. Liste, Tupel)
- bufsize: Puffergröße. Wird beim Erstellen von Pipe-Objekten für Standardstreams verwendet. Standardwert ist -1.
0: Keine Pufferung
1: Zeilenpufferung, nur verfügbar, wenn universal_newlines=True, also im Textmodus
Positive Zahl: Gibt die Puffergröße an
Negative Zahl: Gibt an, dass die Standard-Puffergröße des Systems verwendet werden soll. - stdin, stdout, stderr: Stehen jeweils für die Handles für die Standardeingabe, Standardausgabe und Standardfehler des Programms
- preexec_fn: Nur auf Unix-Plattformen gültig. Wird verwendet, um ein aufrufbares Objekt anzugeben, das aufgerufen wird, bevor der Kindprozess ausgeführt wird.
- shell: Wenn dieser Parameter True ist, wird der angegebene Befehl über die Shell des Betriebssystems ausgeführt.
- cwd: Wird verwendet, um das aktuelle Verzeichnis des Kindprozesses festzulegen.
- env: Wird verwendet, um die Umgebungsvariablen des Kindprozesses anzugeben. Wenn env=None, werden die Umgebungsvariablen des Kindprozesses vom Elternprozess geerbt.
Erstellen Sie einen Kindprozess und führen Sie dann einen einfachen Befehl aus:
Beispiel
>>> p = subprocess.Popen('ls -l', shell=True)
>>> total 164
-rw-r--r-- 1 root root 133 Jul 4 16:25 admin-openrc.sh
-rw-r--r-- 1 root root 268 Jul 10 15:55 admin-openrc-v3.sh
...
>>> p.returncode
>>> p.warten()
0
>>> p.returncode
Sie können auchp = subprocess.Popen(['ls', '-cl'])verwenden, um einen untergeordneten Prozess zu erstellen.
Methoden des Popen-Objekts
- poll(): Prüft, ob der Prozess beendet wurde. Wenn beendet, gibt returncode zurück; andernfalls gibt None zurück.
- wait(timeout): Wartet auf die Beendigung des untergeordneten Prozesses.
- communicate(input,timeout): Interagiert mit dem untergeordneten Prozess, sendet und liest Daten.
- send_signal(signal): Sendet ein Signal an den untergeordneten Prozess.
- terminate(): Beendet den untergeordneten Prozess, das heißt, sendet das SIGTERM-Signal an den untergeordneten Prozess.
- kill(): Tötet den untergeordneten Prozess. Sendet das SIGKILL-Signal an den untergeordneten Prozess.
Beispiel
import subprocess
def cmd(command):
subp = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,encoding="utf-8")
subp.wait(2)
if subp.poll() == 0:
print(subp.communicate()[1])
else:
print("Failed")
cmd("java -version")
cmd("exit 1")
Das Ausgabeergebnis ist wie folgt:
java version "1.8.0_31" Java(TM) SE Runtime Environment (build 1.8.0_31-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode) 失败
Referenzartikel:
https://blog.csdn.net/weixin_42547344/article/details/80894760
https://blog.csdn.net/maosijunzi/article/details/80138458