在不使用 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=PIPE
或stderr=PIPE
。由于当前进程没有读取管道,如果子进程生成足够的输出到管道以填满操作系统管道缓冲区,则子进程可能会阻塞。
问题是,我能找到的几乎每个从子进程获取 stderr 的示例都提到使用 subprocess.PIPE
来捕获该输出。
如何在不使用subprocess.PIPE
的情况下从子进程中捕获stderr?
【问题讨论】:
使用 subprocess.Popen 代替。 【参考方案1】:stdout
和stderr
可以分配给几乎任何可以接收数据的东西,比如文件句柄。您甚至可以提供一个打开的 file_handle 来写入 stdout
和 stderr
:
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的主要内容,如果未能解决你的问题,请参考以下文章
Python subprocess.Popen PIPE和SIGPIPE
passthru() + 子进程中的管道 = Traceback(最近一次调用最后一次):(…)在 stdout=subprocess.PIPE)
在 Python 中对 subprocess.PIPE 进行非阻塞读取