ping无限期的时间并在Python中获取其输出

时间:2015-01-17 00:28:07

标签: python subprocess ping pexpect

任务是:尝试使用最基本的形式如“ping 8.8.8.8”在python中发送ping。一段时间后终止ping命令(在终端中,将执行Ctrl + C)并获取其输出。显示ping统计信息的最后几行输出特别令人感兴趣。

尝试了两种方法,但没有奏效。我的操作系统版本是Mac OS X 10.10.1。

第一种方法使用模块pexpect,并且ping将在大约17秒后停止,但我没有要求它停止:

import pexpect
import time
child = pexpect.spawn('ping 8.8.8.8')
(x, y) = child.getwinsize()
print x
print y
time.sleep(21)
child.terminate()
x = child.read()
print x

第二种方法使用模块子进程,最后几行ping输出丢失:

import time
from subprocess import PIPE, Popen
child = Popen(['ping', '8.8.8.8'], stdin = PIPE, stdout = PIPE, stderr = PIPE)
time.sleep(5)
child.terminate()
x = child.stdout.read()
print x
x = child.stderr.read()
print x

我很感激任何帮助! “ping -c XXX”不被接受。

3 个答案:

答案 0 :(得分:3)

ping一旦填满其stdout OS管道缓冲区(我的系统上约65K)就会阻塞你的代码。您需要阅读输出:

#!/usr/bin/env python
import signal
from subprocess import Popen, PIPE
from threading import Timer

child = Popen(['ping', '8.8.8.8'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
Timer(5, child.send_signal, [signal.SIGINT]).start() # Ctrl+C in 5 seconds
out, err = child.communicate() # get output
print(out.decode())
print('*'*60)
print(err.decode())

答案 1 :(得分:1)

你拥有的第二个解决方案很棒。获得所需行为只是一个问题(获得ping&#34; s&#34;结论&#34;):您正在向流程发送错误的信号。< / p>

当您从shell终止进程时,传统上发送SIGINT信号。见"bash - How does Ctrl-C terminate a child process?"。这使得该过程能够包裹起来&#34; (例如,清理temprorary文件,提供调试信息)。

import signal

# Open process

child.send_signal(signal.SIGINT)

# Provide some time for the process to complete
time.sleep(1)

# Echo output
您现在正在使用的

Popen.terminate会发送SIGTERM而不是SIGINT

答案 2 :(得分:1)

Popen.terminate()在Posix操作系统上发送SIGTERM。但是,默认情况下CTRL + C发送SIGINT。因此,为了获得类似于按CTRL + C的行为,您可以执行以下操作:

...
import signal
...
time.sleep(5)
child.send_signal(signal.SIGINT)
...