没有办法通过像这样的文本管道传递异常stderr
,因为你可以通过文本管道传递的只是文本。
但是有几个选择:
- 确保您的所有孩子在异常时都以非零状态退出(这是默认设置,如果您不做任何事情)并且在任何其他情况下都不要这样做(除非您希望将其视为相同的情况)一个例外)。
- 解析中的异常
stderr
。
- 为父母和孩子创造一些其他的交流渠道来分享。
- 不要使用
subprocess
. 例如,如果您运行 Python 脚本的唯一原因subprocess
是为了获得核心并行性(或内存空间隔离),那么它可能更容易使用multiprocessing
or concurrent.futures
,它已经为您构建了传播异常的机制。
从您的评论中:
我的用例是调用一堆非 Python 第三方的东西。如果返回码是标准库模块传播错误的方式,我很乐意使用它们。
Exception
不,Python 标准库使用s传播错误。你也应该这样。
返回码是非 Python 第三方事物传播错误的方式。(实际上,它们是如何传播错误和意外信号的,但是……不用担心。)这仅限于 7 位的数据,而且含义并没有真正标准化,所以它不是那么好。但这就是 POSIX 子进程模型中的全部内容,所以这就是通用程序所使用的。
您可能想要做的是同样的事情subprocess.check_call
——如果返回码不为零,则引发异常。(事实上,如果你不做任何异步操作,check_call
首先问问自己是否可以使用,而不是Popen
显式使用对象。)
例如,如果您这样做:
output, errors = p.communicate()
将其更改为:
output, errors = p.communicate()
if p.returncode:
raise subprocess.CalledProcessError(p.returncode, 'description')
(描述通常是子进程路径或名称。)
然后,您的其余代码可以只处理异常。