2012-12-26 11 views
8

Wenn ich einen Prozess mit subprocess.Popen in Python aufrufen wie folgt:Prüfstatus von Prozess mit subprocess.Popen in Python

myproc = subprocess.Popen(...).communicate()

was ist der richtige Weg, seinen Status zu sehen? Nicht seine Ausgabe zu stdout oder stderr, aber sein Ausgangsstatus, sobald er beendet ist (z. B. 0 für den Erfolg oder einen anderen für den Fehler)?

Antwort

19

returncode ist in der Tat die Antwort, aber die Lösung muss nicht kompliziert sein.

process = subprocess.Popen(...) 
stdoutdata, stderrdata = process.communicate() 
print process.returncode 

Weitere Informationen in der Python subprocess docs.

+0

ist '' wait'' wirklich erforderlich oder '' communicate() '' '' von Dingen, wenn der Prozess noch läuft? – user248237dfsf

+5

@ user248237 Die Dokumentation sagt "Rückkehrcode, eingestellt durch' poll() 'und' wait() '(und indirekt durch' communicate() ')." So sollte 'communicate()' sich darum kümmern, auf den Prozess zu warten. –

1

Sie müssen möglicherweise einen wait auf Ihrem Subprozess aufrufen und dann (einmal durchgeführt) den Status im Feld returncode der Subprozessinstanz überprüfen.

Ich habe eine kleine Routine, die Sachen nennt, wird es vielleicht ... helfen

def singleProcessExecuter(command, ** kwargs): 
    assert isinstance(command, list), "Expected 'command' parameter to be a list containing the process/arguments to execute. Got %s of type %s instead" % (command, type(command)) 
    assert len(command) > 0, "Received empty list of parameters" 
    retval = { 
      "exitCode": -1, 
      "stderr": u"", 
      "stdout": u"", 
      "execTime": datetime.timedelta(0), 
      "command": None, 
      "pid": None 
      } 
    retval["command"] = command 
    log.info("::singleProcessExecuter > At %s, executing \"%s\"" % (datetime.datetime.now(), " ".join(command))) 
    #print("::singleProcessExecuter > At %s, executing \"%s\"" % (datetime.datetime.now(), " ".join(parameter))) 
    cwd = kwargs.get("cwd", os.getcwd()) 
    user = kwargs.get("user", getUid()) 
    sheel = kwargs.get("shell", False) 
    startDatetime = datetime.datetime.now() 
    myPopy = subprocess.Popen(command, cwd=cwd, preexec_fn=os.seteuid(getUid(user)), shell=sheel, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) 
    retval["pid"] = myPopy.pid 
    log.debug("::singleProcessExecuter > Command \"%s\" got pid %s" % (" ".join(command), myPopy.pid)) 
    try: 
     retval["stdout"], retval["stderr"] = myPopy.communicate() 
     myPopy.wait() 
    except OSError, osErr: 
     log.debug("::singleProcessExecuter > Got %s %s in myPopy.communicate() when trying get output of command %s. It is probably a bug (more info: http://bugs.python.org/issue1731717)" % (osErr, type(osErr), command[0])) 
    except Exception, e: 
     log.warn("::singleProcessExecuter > Got %s %s when trying to get stdout/stderr outputs of %s" % (type(e), e, " ".join(command))) 
     log.debug("::singleProcessExecuter > Got %s %s when trying to get stdout/stderr outputs of %s. Showing traceback:\n%s" % (type(e), e, " ".join(command), traceback.format_exc())) 
     raise 
    retval["exitCode"] = myPopy.returncode 
    retval["execTime"] = datetime.datetime.now() - startDatetime 
    #print(":singleProcessExecuter > This is %s's retval:\n%s" % (" ".join(parameter), retval)) 
    return retval 

Sie können es versuchen, mit:

print "This is the return: %s" % singleProcessExecuter(["ls", "-la"]) 
+0

Ich mag deinen Code wirklich! Ich weiß, dass es schon ein paar Jahre her ist, aber ich würde mich freuen, die dafür notwendigen Importe zu sehen! – schneiti

4

Ein Prozess hat keinen Rückgabecode, bis die Ausführung abgeschlossen ist. Wenn Sie also noch nicht fertig sind, müssen Sie entscheiden, was Sie tun möchten: warten Sie darauf oder geben Sie einen Indikator von "Ich bin noch nicht fertig" zurück. Wenn Sie warten möchten, verwenden Sie communicate und überprüfen Sie dann das returncode Attribut.

Wenn Sie überprüfen möchten, ob der Rückkehrcode festgelegt ist, und None zurückgeben, falls nicht, verwenden Sie Popen.poll().

Verwandte Themen