【问题标题】:Reading on-going process output from stdout using subprocess.Popen()使用 subprocess.Popen() 从标准输出读取正在进行的进程输出
【发布时间】:2023-09-18 21:45:01
【问题描述】:

我想使用 subprocess.Popen() 和 subprocess.communicate() 从代码(在后台运行)读取已启动进程的持续输出

开始进程:

import subprocess
process_params = ['/usr/bin/tcpdump', '-n', 'dst port 80']

proc = subprocess.Popen(
    process_params,
    stdout=subprocess.PIPE, stderr=subprocess.PIPE
)

(stdout, stderr) = proc.communicate()

tcpdump 进程在后台运行,但 proc.communicate() 一直等到文件结束,只有当进程被杀死时才会产生一些输出。

>>> (stdout, stderr) = proc.communicate()

我想在进程产生输出时实现类似从进程的标准输出接收数据的功能。 我想我需要一些线程来查看是否从进程生成了一些输出,然后例如将其附加到日志文件中。 我不知道该怎么做,所以任何想法和建议都将不胜感激。

【问题讨论】:

  • 看看我的回答*.com/a/49209440/7738328stdout 流在线程中被捕获并在写入日志之前被修改。我认为这与您的用例相似?

标签: python subprocess stdout


【解决方案1】:

tcpdump 可能正在缓冲其输出。只有当它有一个充满数据的缓冲区(通常为 8KB)要写入时,它才会写入输出。这是不写入 TTY 的程序的常见行为。

Tcpdump 有一个命令行选项来对它的输出进行行缓冲。这会导致它在每次有整行文本时写入输出。试试这个:

process_params = ['/usr/bin/tcpdump', '-l', '-n', 'dst port 80']
                                       ^^--Line buffer output

或者,查看您的系统上是否安装了名为 stdbufunbuffer 的程序。它们可用于调整另一个进程的缓冲行为。或查看以下问题:

【讨论】:

  • 虽然这是真的,但使 tcpdump 无缓冲并不能解决问题,因为 p.communicate 在子进程完成之前不会返回。因此,对于stdout 输出,仍然需要线程解决方案。
  • 感谢 Kenster 对 -l 参数的想法,结合 JohanL 回答 tcpdump 输出正确保存到文件:)
最近更新 更多