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

Python with tcpdump in a subprocess: how to close subprocess properly?

我有一个 Python 脚本来捕获 tcpdumpsubprocess 中的网络流量:

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

当这个脚本完成它的工作时,我试图在 Wireshark 中打开输出 .pcap 文件并得到这个 error:

"The capture file appears to have been cut short in the middle of a packet."

"proper" 关闭 tcpdumpsubprocess 可以应用什么解决方案?

找到可行的解决方案:
我已将 p.kill() 更改为 p.terminate()
此更改后 subprocess 已 "properly" 完成(tcpdump 子进程的输出,控制台中提供统计信息)并且输出 .pcap 文件未损坏。

您可以使用 p.send_signal(subprocess.signal.SIGTERM) 代替 p.kill() 发送终止信号而不是终止信号(p.terminate() 也是如此)。

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

我在关闭 subprocesses 时遇到了同样的问题。这个帖子真的很有帮助,所以特别感谢 https://whosebug.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()、and/or output.terminate() 或发送 output.send_signal(subprocess.signal.SIGTERM) 无效,但 output.TerminateProcess() 有效。