使用下面的代码,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',''): 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可能会失败.