问题
I want to do something similar to the second answer here (but not quite similar): Simulate Ctrl-C keyboard interrupt in Python while working in Linux
It's much simpler and I think I'm just missing something. Say, from a python script, I just want to call 'ping' and terminate it after the 10th time. I'm trying to do it like from the link above:
p = subprocess.Popen(['ping', 'google.com'], stdout=subprocess.PIPE)
for line in p.stdout:
print line
if re.search('10', line):
break
os.kill(p.pid, signal.SIGINT)
But it doesn't work.
And I also want the regular output of 'ping' to be displayed. How do I do this?
EDIT: It's not actually a 'ping' that I want to do. I'm just using it as an example of a command with continuous output, which in time, I would like to terminate.
More specifically, I'm running an old version of BitTorrent (v5.0.9 from the 3rd answer here: Where to find BitTorrent source code?) and I'm calling it via python script. The bittorrent-console.py is a simple terminal version, hence 'console'. It outputs multiple lines periodically. Something like:
saving: filename
file size: blah
percent done: 100.0
blah: blahblah
I'm actually calling it by:
subprocess.call(['./bittorrent-console.py', 'something.torrent'])
I want to terminate it automatically when I see it's 100.0 in 'percent done:'.
EDIT: I'm running on CentOS, Python 2.6.
回答1:
Firstly, you want to use p.stdout.readline
. I'm not sure why, but for line in p.stdout
doesn't seem to flush. Perhaps it's buffered.
Secondly, you should use sys.stdout.write(line)
, because print
always appends something. In Python 3 you can use print(line, end="")
, though.
Also, you should prefer p.kill
to os.kill
. I'm not sure why you're using os.kill
.
import os
import signal
import subprocess
import sys
p = subprocess.Popen(['ping', 'google.com'], stdout=subprocess.PIPE)
while True:
line = p.stdout.readline()
sys.stdout.write(line)
sys.stdout.flush()
if '10' in line:
break
p.kill()
回答2:
This does exactly what you want and works perfectly on my OS X machine:
import subprocess
import re
def get_output(cmd, until):
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
ret = []
while True:
line = p.stdout.readline()
ret.append(line)
if re.search(until, line):
break
p.kill()
return ret
print ''.join(get_output(['ping', 'google.com'], until='10'))
来源:https://stackoverflow.com/questions/19059294/catching-terminal-output-in-python