用子进程检查进程的状态。Popen在Python中

时间:2022-11-03 14:55:51

If I invoke a process with subprocess.Popen in Python as follows:

如果我调用一个带有子进程的进程。Python中的Popen如下:

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

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

what is the correct way to see its status? Not its output to stdout or stderr, but its exit status once it's finished (e.g. 0 for success or another for failure)?

正确的方式是什么?不是输出到stdout或stderr,而是输出完成后的退出状态(例如,0表示成功,另一个表示失败)?

3 个解决方案

#1


19  

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

returncode确实是答案,但是解决方案不需要太复杂。

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

More info in the Python subprocess docs.

更多关于Python子进程文档的信息。

#2


5  

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.

如果您想等待,使用通信,然后检查returncode属性。

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

如果您想检查返回代码是否设置,如果没有,返回None,请使用Popen.poll()。

#3


1  

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.

您可能需要在子进程上调用wait,然后(一旦完成)检查子进程实例的returncode字段中的状态。

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"])

#1


19  

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

returncode确实是答案,但是解决方案不需要太复杂。

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

More info in the Python subprocess docs.

更多关于Python子进程文档的信息。

#2


5  

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.

如果您想等待,使用通信,然后检查returncode属性。

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

如果您想检查返回代码是否设置,如果没有,返回None,请使用Popen.poll()。

#3


1  

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.

您可能需要在子进程上调用wait,然后(一旦完成)检查子进程实例的returncode字段中的状态。

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"])