任务是:尝试使用最基本的形式如“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”不被接受。
答案 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)
...