【问题标题】:Unable to print TCPcump information using python subprocess无法使用python子进程打印TCPcump信息
【发布时间】:2022-11-21 17:32:53
【问题描述】:

我想在 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 pf 中只有一行,有没有办法读取?

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

【问题讨论】:

  • 切线地,你放在if __name__ == '__main__': 中的代码应该是绝对微不足道的。该条件仅在您import此代码时才有用;如果当您import 时所有有用的功能都被排除在外,您将永远不想这样做。另见stackoverflow.com/a/69778466/874188

标签: python ubuntu networking scripting subprocess


【解决方案1】:

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

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

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

$ 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 的向后兼容别名,因此应首选后者。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多