在不使用 subprocess.PIPE 的情况下在 subprocess.check_call 中捕获 stderr

Posted

技术标签:

【中文标题】在不使用 subprocess.PIPE 的情况下在 subprocess.check_call 中捕获 stderr【英文标题】:Catch stderr in subprocess.check_call without using subprocess.PIPE 【发布时间】:2012-12-30 08:00:59 【问题描述】:

我想做以下事情:

使用subprocess.check_call从 Python 中转到另一个可执行文件 捕获子进程的stderr,如果有的话 将 stderr 输出添加到父进程的 CalledProcessError 异常输出中。

理论上这很简单。 check_call 函数签名包含 stderr 的 kwarg:

subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False)

但是,紧接着documentation 包含以下警告:

注意:请勿在此功能中使用stdout=PIPEstderr=PIPE。由于当前进程没有读取管道,如果子进程生成足够的输出到管道以填满操作系统管道缓冲区,则子进程可能会阻塞。

问题是,我能找到的几乎每个从子进程获取 stderr 的示例都提到使用 subprocess.PIPE 来捕获该输出。

如何在不使用subprocess.PIPE 的情况下从子进程中捕获stderr?

【问题讨论】:

使用 subprocess.Popen 代替。 【参考方案1】:

stdoutstderr 可以分配给几乎任何可以接收数据的东西,比如文件句柄。您甚至可以提供一个打开的 file_handle 来写入 stdoutstderr

file_handle = open('some_file', 'w')

subprocess.check_call(args, *, stdin=None, stdout=file_handle, stderr=file_handle, shell=False)

现在每行输出都转到同一个文件,或者您可以为每个输出一个不同的文件。

stdin 也读起来像一个文件句柄,使用next() 读取每一行作为输入命令,除了初始的args 之外要继续发送。

它是一个非常强大的功能。

【讨论】:

有没有办法将 stdout/err 捕获到变量中以便我可以记录它?

以上是关于在不使用 subprocess.PIPE 的情况下在 subprocess.check_call 中捕获 stderr的主要内容,如果未能解决你的问题,请参考以下文章

从 async.subprocess.PIPE 读取

Python subprocess.Popen PIPE和SIGPIPE

passthru() + 子进程中的管道 = Traceback(最近一次调用最后一次):(…)在 stdout=subprocess.PIPE)

在 Python 中对 subprocess.PIPE 进行非阻塞读取

在 Python 中对 subprocess.PIPE 进行非阻塞读取

在 Python 中对 subprocess.PIPE 进行非阻塞读取