checking status of process with subprocess.Popen in Python

You may need to call a wait on your subprocess and then (once is done) check the status in the returncode field of the subprocess instance.

I have a little routine that calls stuff, maybe it'll help...

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

You can try it with:

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

A process doesn't have a return code until it's finished executing. Therefore, if it hasn't yet finished, you have to decide what you want to do: wait for it, or return some indicator of "I haven't finished yet".

If you want to wait, use communicate and then check the returncode attribute.

If you want to check whether the return code is set, and return None if not, use Popen.poll().

Popen.poll()

Check if child process has terminated. Set and return returncode attribute.

(if process hasn't terminated, poll() returns None)


returncode is indeed the answer, but the solution doesn't need to be complicated.

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

More info in the Python subprocess docs.