ubuntu 无法使用python子进程打印TCP累积信息

7hiiyaii  于 2022-11-22  发布在  Python
关注(0)|答案(1)|浏览(141)

我想在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")

这是我从this previously asked question.的第二个答案中了解到的。虽然它没有等待子进程完成来打印tcpdump的输出,但我仍然一次获得20-30行的输出。即使子进程的stdout中只有一行,是否有办法读取?
PS:我在ubuntu服务器22.04.1的树莓派4上运行这个脚本

j5fpnvbx

j5fpnvbx1#

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

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

第一个命令一次打印一行。第二个命令将所有内容收集到一个缓冲区中,并在tcpdump退出时打印所有内容。解决方法是告诉tcpdump使用带有-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的向后兼容别名,因此应首选后者。

相关问题