4

我想做类似于这里的第二个答案的事情(但不太相似):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:在哪里可以找到 BitTorrent 源代码?),我通过 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 上运行。

4

2 回答 2

2

首先,您要使用p.stdout.readline. 我不知道为什么,但for line in p.stdout似乎没有冲洗。也许它被缓冲了。

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

此外,您应该更p.kill喜欢os.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()
于 2013-09-27T20:53:39.517 回答
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'))
于 2013-09-27T21:13:29.177 回答