在Python中捕获终端输出

时间:2013-09-27 20:12:00

标签: python terminal output

我想在这里做类似于第二个答案的事情(但不太相似):Simulate Ctrl-C keyboard interrupt in Python while working in Linux

它更简单,我想我只是缺少一些东西。比方说,从python脚本,我只想调用'ping'并在第10次后终止它。我试图通过上面的链接来做到这一点:

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)

但它不起作用。

我还希望显示'ping'的常规输出。我该怎么做呢?

编辑:这实际上并不是我想做的'ping'。我只是用它作为连续输出命令的一个例子,我想及时终止。

更具体地说,我正在运行旧版本的BitTorrent(来自第3个答案的v5.0.9:Where to find BitTorrent source code?),我正在通过python脚本调用它。 bittorrent-console.py是一个简单的终端版本,因此是“控制台”。它定期输出多行。类似的东西:

saving:       filename
file size:    blah
percent done: 100.0
blah:         blahblah

我实际上是通过以下方式调用它:

subprocess.call(['./bittorrent-console.py', 'something.torrent'])

我想在'百分之百完成'中看到它是100.0时自动终止它。

编辑:我正在运行CentOS,Python 2.6。

2 个答案:

答案 0 :(得分:2)

首先,您要使用p.stdout.readline。我不确定为什么,但for line in p.stdout似乎没有冲洗。也许它是缓冲的。

其次,您应该使用sys.stdout.write(line),因为print总是附加一些内容。在Python 3中,您可以使用print(line, end="")

此外,您应该更喜欢p.killos.kill。我不确定你为什么要使用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()

答案 1 :(得分:2)

这正是您想要的,并且在我的OS X机器上完美运行:

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'))