如何在使用Python子进程的communicate方法时获取退出代码?

252 投票
8 回答
398413 浏览
提问于 2025-04-16 15:33

我该如何在使用Python的subprocess模块和communicate()方法时获取退出代码呢?

相关代码:

import subprocess as sp
data = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE).communicate()[0]

我是不是应该用其他方法来做这个呢?

8 个回答

21

.poll() 这个方法会更新返回码。

你可以试试

child = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE)
returnCode = child.poll()

另外,在调用了 .poll() 之后,你可以通过 child.returncode 来查看这个返回码。

24

我想提醒大家一个常见的误解,尽量避免使用 Popen,除非真的没有其他选择。根据官方文档的说法:

推荐的方式是使用 run() 函数来调用子进程,这个方法适用于大多数情况。如果你有更复杂的需求,可以直接使用底层的 Popen 接口。

如果你只是想运行一个子进程并等待它完成,只需要一行代码就可以用 subprocess.run,或者它的老方法 subprocess.callsubprocess.check_output。这样你就不需要去复制粘贴或者理解 Popen 这个低级对象周围那些复杂的 communicatewait 方法。

import subprocess

proc = subprocess.run(
    [openRTSP] + opts.split(),
    capture_output=True,
    # avoid having to explicitly encode
    text=True)
data = proc.stdout
result = proc.returncode

如果你不想获取进程的输出,可以把 capture_output=True 替换成 stdout=subprocess.DEVNULL(也可以对 stderr 做类似处理);如果不设置这两个,输出会直接显示给用户,而不在 Python 的控制之下。

另外,除非你的 opts 选项非常简单,一般来说,建议把普通的字符串 split() 替换成 shlex.split(),这样可以更好地处理带引号的字符串。

359

Popen.communicate 在完成后会设置 returncode 属性(*). 下面是相关的文档部分:

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

所以你可以这样做(我没测试过,但应该可以):

import subprocess as sp
child = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE)
streamdata = child.communicate()[0]
rc = child.returncode

(*) 之所以会这样,是因为它的实现方式:在设置好线程来读取子进程的输出流后,它就会调用 wait

撰写回答