Ich möchte prüfen, ob ein Unterprozess erfolgreich ausgeführt wurde oder fehlgeschlagen ist. Momentan habe ich eine Lösung gefunden, bin aber nicht sicher, ob sie korrekt und zuverlässig ist. Ist sichergestellt, dass jeder Prozess seine Fehler nur an respektvoll an stdout
an stderr ausgibt:
Hinweis: Ich bin nicht daran interessiert, die Ausgabe nur umzuleiten/auszudrucken. Dass ich schon weiß, wie es geht.
pipe = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True)
if "" == pipe.stdout.readline():
print("Success")
self.isCommandExectutionSuccessful = True
if not "" == pipe.stderr.readline():
print("Error")
self.isCommandExectutionSuccessful = True
alternative:
if "" == pipe.stdout.readline():
print("Success")
self.isCommandExectutionSuccessful = True
else:
print("Error")
self.isCommandExectutionSuccessful = False
und:
if not "" == pipe.stderr.readline():
print("Success")
self.isCommandExectutionSuccessful = True
else:
print("Error")
self.isCommandExectutionSuccessful = False
Müssen Sie etwas mit der Ausgabe des Prozesses tun?
Die check_call
-Methode kann hier hilfreich sein. Die Python-Dokumente finden Sie hier: https://docs.python.org/2/library/subprocess.html#subprocess.check_call
Sie können dies dann wie folgt verwenden:
try:
subprocess.check_call(command)
except subprocess.CalledProcessError:
# There was an error - command exited with non-zero code
Dies setzt jedoch voraus, dass command
für einen erfolgreichen Abschluss einen Exit-Code von 0 und einen Fehlerwert ungleich Null zurückgibt.
Wenn Sie auch die Ausgabe erfassen müssen, ist die check_output
-Methode möglicherweise geeigneter. Es ist immer noch möglich, den Standardfehler umzuleiten, wenn Sie diesen auch benötigen.
try:
proc = subprocess.check_output(command, stderr=subprocess.STDOUT)
# do something with output
except subprocess.CalledProcessError:
# There was an error - command exited with non-zero code
Die Dokumente finden Sie hier: https://docs.python.org/2/library/subprocess.html#subprocess.check_output
Sie können den Rückgabecode des Prozesses mithilfe der check_call () - Methode überprüfen. Wenn in diesem Prozess ein Wert ungleich Null zurückgegeben wird, wird CalledProcessError ausgelöst.
output,error=pipe.communicate()
Dies wartet, bis der Befehl beendet ist und gibt je nach Befehlsstatus Ausgabe oder Fehler aus.
Komplettlösung mit Check auf Returncode, stdout und stderr:
import subprocess as sp
# ok
pipe = sp.Popen( 'ls /bin', Shell=True, stdout=sp.PIPE, stderr=sp.PIPE )
# res = Tuple (stdout, stderr)
res = pipe.communicate()
print("retcode =", pipe.returncode)
print("res =", res)
print("stderr =", res[1])
for line in res[0].decode(encoding='utf-8').split('\n'):
print(line)
# with error
pipe = sp.Popen( 'ls /bing', Shell=True, stdout=sp.PIPE, stderr=sp.PIPE )
res = pipe.communicate()
print("retcode =", pipe.returncode)
print("res =", res)
print("stderr =", res[1])
Drucke:
retcode = 0
res = (b'bash\nbunzip2\nbusybox\nbzcat\n...zmore\nznew\n', b'')
stderr = b''
bash
bunzip2
busybox
bzcat
...
zmore
znew
retcode = 2
res = (b'', b"ls: cannot access '/bing': No such file or directory\n")
stderr = b"ls: cannot access '/bing': No such file or directory\n"
So habe ich es endlich geschafft:
# Call a system process
try:
# universal_newlines - makes manual decoding of subprocess.stdout unnecessary
output = subprocess.check_output(command,
stderr=subprocess.STDOUT,
universal_newlines=True)
# Print out command's standard output (elegant)
for currentLine in output:
self.textEdit_CommandLineOutput.insertPlainText(currentLine)
self.isCommandExecutionSuccessful = True
except subprocess.CalledProcessError as error:
self.isCommandExecutionSuccessful = False
errorMessage = ">>> Error while executing:\n"\
+ command\
+ "\n>>> Returned with error:\n"\
+ str(error.output)
self.textEdit_CommandLineOutput.append(errorMessage)
QMessageBox.critical(None,
"ERROR",
errorMessage)
print("Error: " + errorMessage)
except FileNotFoundError as error:
errorMessage = error.strerror
QMessageBox.critical(None,
"ERROR",
errorMessage)
print("Error: ", errorMessage)
Ich hoffe, es wird jemand anderem nützlich sein.