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

2024-10-01 00:34:07 发布

您现在位置:Python中文网/ 问答频道 /正文

使用下面的代码,p.returncode总是None。根据^{} 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

请注意:我之所以分别阅读每一行,是因为我想实时过滤其他长时间运行的进程的输出,并基于某些字符串停止它们。

我在Python2.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)

Tags: 代码importcmdreturn进程stdoutsysline
1条回答
网友
1楼 · 发布于 2024-10-01 00:34:07

根据链接到文档

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).

您尚未调用pollwait,因此不会设置returncode

另一方面,如果您查看fxcheck_output的源代码,您会发现它们直接使用来自poll的返回值来检查返回代码。他们知道进程在那一点上已经终止,因为他们已经在前面调用了wait。如果您不知道您将不得不调用wait方法(但请注意文档中指出的死锁可能性)。

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

相关问题 更多 >