如何从subprocess.Popen获取退出代码?

使用下面的代码,p.returncode始终为None.根据 Popen.returncode documentation,这意味着该过程尚未完成.

为什么我没有获得退出代码?

import os
import sys
import subprocess

cmd = ['echo','hello']
p = subprocess.Popen(cmd,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.STDOUT)
try:
    # Filter stdout
    for line in iter(p.stdout.readline, ''):
        sys.stdout.flush()
        # Print status
        print(">>> " + line.rstrip())
        sys.stdout.flush()
except:
    sys.stdout.flush()

print 'RETURN CODE', p.returncode

请注意:我之所以单独阅读每一行是因为我想实时过滤其他长期运行的进程的输出,并根据某些字符串暂停它们.

我使用的是Python 2.7.5(CentOS 7 64位).

感谢@skyking发布的答案,我现在可以成功捕获这样的退出代码,使用Popen.poll()(Popen.wait()死锁我的进程):

import os
import sys
import subprocess
import time

cmd = ['echo','hello']
p = subprocess.Popen(cmd,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.STDOUT)
try:
    # Filter stdout
    for line in iter(p.stdout.readline, ''):
        sys.stdout.flush()
        # Print status
        print(">>> " + line.rstrip())
        sys.stdout.flush()
except:
    sys.stdout.flush()

# Wait until process terminates (without using p.wait())
while p.poll() is None:
    # Process hasn't exited yet, let's wait some
    time.sleep(0.5)

# Get return code from process
return_code = p.returncode

print 'RETURN CODE', return_code

# Exit with return code from process
sys.exit(return_code)
根据文档链接

The child return code, set by poll() and wait() (and indirectly by
communicate()). A None value indicates that the process hasn’t terminated yet.

A negative value -N indicates that the child was terminated by signal N (Unix only).

您尚未调用poll或wait,因此不会设置returncode.

另一方面,如果你查看fx check_output的源代码,你会发现它们直接使用poll的返回值来检查返回代码.他们知道这个过程已经终止,因为他们已经提前等待了.如果您不知道必须调用wait方法(但请注意文档中记录的死锁可能性).

通常情况下,当你读完stdout / stderr时,程序会终止,但这不能保证,这可能就是你所看到的.程序或操作系统可以在进程实际终止之前关闭stdout(和stderr),然后在读完程序的所有输出后立即调用poll可能会失败.

本站公众号
   欢迎关注本站公众号,获取更多程序园信息
开发小院