子进程的过滤标准捕获空字节



我正在调用一个非常嘈杂的 CLI 命令,想要过滤输出,大概是 stderr。CLI 二进制文件的输出形状像 python 日志记录,信息:...或警告:....在 shell 中运行时,CLI 命令首先有几个"设置"日志,几秒钟后,每秒几十个的实际日志开始。

我试图像这样对 stderr 进行管道处理,并且肯定还有 stdout:

process = subprocess.Popen(cmd, 
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
while process.stderr:
line = process.stderr.readline()
print("STDERR", line)
while process.stdout:
line = process.stdout.readline()
print("STDOUT", line)

这有效,并且 STDERR 打印显示在 CLI 命令执行的第一个位。但是,当我在几秒钟后到达该部分时,STDERR 打印的输出仅为b''— 可能与正常 shell 调用输出额外日志的频率相同。我也尝试过read()而不是readline()但无济于事。("STDOUT"永远不会被叫,顺便说一句)

不知何故,在常规 shell 调用中记录的输出不同或太频繁(?)或不完整(?),以至于 PIPE 无法发送它并正确读取和打印它。

我该怎么做才能进一步调试?

一个选项是将那些 while 循环替换为:

for line in iter(process.stderr.readline, b''):
print("STDERR", line)

这至少可以处理这样一个事实,即即使没有什么可读的,process.stderr也不会变得虚假。

最新更新