无法使用 python 子进程打印 TCPcump 信息

Unable to print TCPcump information using python subprocess

提问人:Vibhore Jain 提问时间:11/19/2022 更新时间:11/21/2022 访问量:87

问:

我想在 python 脚本中处理 tcpdump 输出,到目前为止,我能够实现这个实现

from subprocess import Popen, PIPE, CalledProcessError
import os
import signal
import time

if __name__=="__main__":
    
    cmd = ["sudo","tcpdump", "-c","1000","-i","any","port","22","-n"]
    with Popen(cmd, stdout=PIPE, bufsize=1, universal_newlines=True) as p:
        try:
            for line in p.stdout:
                print(line,flush=True) # process line here   
    
        except KeyboardInterrupt:       
            print("Quitting")

这就是我从前面提出的问题的第二个答案中得出的结论。虽然它没有等待子进程完成以打印 tcpdump 的输出,但我仍然一次以 20-30 行的块形式获得输出。即使子进程的 stdout 中只有一行,有没有办法读取?

PS:我在带有 ubuntu 服务器 4 的树莓派 22.04.1 上运行此脚本

Python Ubuntu 网络 脚本 子进程

评论

1赞 tripleee 11/20/2022
切线地,你放在里面的代码应该是绝对微不足道的。该条件仅在您使用此代码时有用;如果所有有用的功能都被排除在外,那么无论如何你都不会想这样做。另请参阅 stackoverflow.com/a/69778466/874188if __name__ == '__main__':importimport

答:

1赞 tfpf 11/21/2022 #1

tcpdump如果将其标准输出连接到管道,则使用更大的缓冲区。您可以通过运行以下两个命令轻松看到这一点。(我将计数从 1000 更改为 40 并删除,以便快速在我的系统上获得输出。port 22

$ sudo tcpdump -c 40 -i any -n
$ sudo tcpdump -c 40 -i any -n | cat

第一个命令一次打印一行。第二个将所有内容收集到缓冲区中,并在退出时打印所有内容。解决方案是告诉对参数使用行缓冲。tcpdumptcpdump-l

$ sudo tcpdump -l -c 40 -i any -n | cat

在 Python 程序中执行相同的操作。

import subprocess

cmd = ["sudo", "tcpdump", "-l", "-c", "40", "-i", "any", "-n"]
with subprocess.Popen(cmd, stdout=subprocess.PIPE, bufsize=0, text=True) as p:
    for line in p.stdout:
        print(line.strip())

当我运行它时,我一次打印一行。

请注意,这是 的向后兼容别名,因此应首选后者。universal_newlinestext