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.