webentwicklung-frage-antwort-db.com.de

"subprocess.Popen" - Überprüfung auf Erfolg und Fehler

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
17
Zingam

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

21
elParaguayo

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.

3
Alexey Bureev
      output,error=pipe.communicate()

Dies wartet, bis der Befehl beendet ist und gibt je nach Befehlsstatus Ausgabe oder Fehler aus.

1
vks

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"
1
PJ_Finnegan

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.

0
Zingam