Python中使用tcpdump子进程:如何正确关闭子进程?

6

我有一个Python脚本,使用subprocess调用tcpdump来捕获网络流量:

p = subprocess.Popen(['tcpdump', '-I', '-i', 'en1',
                  '-w', 'cap.pcap'], stdout=subprocess.PIPE)
time.sleep(10)
p.kill()

当这个脚本完成工作后,我试图在Wireshark中打开输出.pcap文件,但是出现了以下错误:

"捕获文件似乎在包的中间被截断了。"

有什么解决方案可以用于“正确”关闭tcpdumpsubprocess吗?

p.wait() 应该等待进程完成。我认为这时进程已经“关闭”了? - roganjosh
1
在我的情况下,这是一个“无限”的过程(直到用户或计时器关闭它)。 - olpo.graphy
你的程序中是否使用了 p.kill() 或者其他方式来中断程序? - tijko
我在程序中使用 p.kill(),在捕获10秒后执行。 - olpo.graphy
3个回答

6

你可以使用 p.send_signal(subprocess.signal.SIGTERM) 来发送终止信号,而不是使用 p.kill()p.terminate() 也是相同的)。

Popen 文档 描述了 send_signal() 命令。关于信号的文档有些薄弱,但是通过 dir(subprocess.signal) 可以列出所有可以发送给进程的信号,而 terminate 应该允许它一些时间来清理。


2
发现了可行的解决方案:
我将 p.kill() 更改为 p.terminate()
这个更改后,subprocess 被“正确”结束(在控制台中输出有统计信息的 tcpdump 子进程),并且输出的 .pcap 文件没有损坏。

1

我遇到了与关闭subprocess相关的问题。这个线程真的很有帮助,所以谢谢大家,特别是https://stackoverflow.com/users/3583715/rkh。我的解决方案:

之前:

output = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
message = output.stdout.read()
output.stdout.close()

阅读Popen文档之后:

output = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
message = output.stdout.read()
output.TerminateProcess()

由于某些原因,调用 output.kill()output.terminate() 或发送 output.send_signal(subprocess.signal.SIGTERM) 均无法生效,但是 output.TerminateProcess() 可以。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接