遍历subprocess输出中断循环,使用TextIOWrapper为何返回非零退出码?
退出码-13的原因说明
退出码 -13 对应Unix-like系统下的SIGPIPE信号:当进程尝试往已经关闭读端的管道写数据时,操作系统会向该进程发送SIGPIPE信号强制终止进程,Python的subprocess模块会把被信号终止的进程返回码设为对应信号编号的负值,SIGPIPE的标准编号为13,因此返回码为-13。
两段代码的差异点解释
- 第一段代码直接遍历
process.stdout:subprocess.Popen返回的stdout是原生的字节流BufferedReader对象,你在循环中break后,这个读端管道并不会被自动关闭,后续调用process.wait()时,子进程仍然可以正常往管道中写入剩余输出,运行结束后正常返回0。 - 第二段代码用
TextIOWrapper包裹后遍历:io.TextIOWrapper的迭代逻辑在提前终止(这里的break)后,会自动关闭它所包裹的底层IO流,也就是直接关闭了管道的读端。此时子进程还在往标准输出写数据,触发了SIGPIPE信号被系统强制杀死,因此最终返回码为-13。
如果要避免这个问题,可以在初始化TextIOWrapper时添加closefd=False参数,让它不要自动关闭底层流:
for line in io.TextIOWrapper(process.stdout, encoding="utf-8", closefd=False):
内容的提问来源于stack exchange,提问作者Johnny Baloney
相关产品推荐
相关产品推荐

