【问题标题】:Python with tcpdump in a subprocess: how to close subprocess properly?子进程中带有 tcpdump 的 Python:如何正确关闭子进程?
【发布时间】:2017-03-01 14:26:48
【问题描述】:

我有一个 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() 应该等到该过程完成。我认为这个过程是“关闭的”?
  • 在我的情况下,它是“无限”过程(直到用户或计时器不关闭它)
  • 您是在程序中使用p.kill() 还是通过其他方式中断?
  • 捕获 10 秒后,我在程序中使用 p.kill()

标签: python python-2.7 subprocess tcpdump


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      我在关闭subprocesses 时遇到了同样的问题。这个线程真的很有帮助,所以谢谢,特别是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() 起作用。

      【讨论】:

        猜你喜欢
        • 2015-12-05
        • 2015-07-07
        • 2013-07-19
        • 1970-01-01
        • 2011-12-30
        • 1970-01-01
        • 2013-05-03
        • 2011-04-13
        • 2017-01-09
        相关资源
        最近更新 更多