终止tcpdump子进程后如何获取stdout

7 投票
1 回答
5114 浏览
提问于 2025-04-17 00:12

我在一个子进程中运行 tcpdump,代码是这样的:

pcap_process = subprocess.Popen(['tcpdump', '-s 0', '-w -', 'tcp'], 
                                  stdout=subprocess.PIPE, stderr=subprocess.PIPE)

这里的 -w - 参数很重要:它告诉 tcpdump 把生成的 .pcap 文件输出到 stdout,也就是标准输出。

接下来,我使用 urllib.open() 访问一个网站。完成这个后,我想结束 tcpdump 的进程,并把它输出的内容放到一个字符串里。我尝试了以下方法:

pcap_process.terminate()
result = pcap_process.stdout.read()    # or readline(), etc.

但是(除非我做错了什么),这样并不奏效;我结束了进程,现在没有任何东西可以读取。如果我在结束之前使用 read()communicate(),我的脚本就会一直等待,试图读取,直到 tcpdump 完成(但它不会完成)。

有没有办法做到这一点(最好不要用循环)?

1 个回答

8

与其使用tcpdump,通常建议直接使用PCAP,或者Scapy

如果这两个选项都不可行,那就可以在调用terminate之后再调用communicate。因为结束一个进程并不会把发送到它的管道里的数据也结束掉。不过,创建子进程时要记得把参数分开(用[,'-w', '-']而不是[... , '-w -', ..]):

pcap_process = subprocess.Popen(['tcpdump', '-s', '0', '-w', '-', 'tcp'],
                                  stdout=subprocess.PIPE, stderr=subprocess.PIPE)

撰写回答