在调用进程仍在运行时使用python读取命令行输出

时间:2014-12-20 12:33:58

标签: python subprocess

似乎有很多方法可以使用python通过命令行调用某些系统进程,然后在进程完成后读取输出 。例如,subprocess模块可以通过subprocess.Popen(['ls'])完成此操作。

有没有办法在命令运行时读取的输出

例如,如果我调用python脚本multiply.py

import time

def multiply(a,b):
    newA = a
    newB = b
    while True: #endless loop
        newA = newA+1
        newB = newB+1

        product = newA * newB
        print 'Product: ',product
        time.sleep(1)


multiply(40,2)

使用subprocess.Popen(['python', 'multiply.py])行的内容,有没有办法

  1. 启动流程
  2. 在进程运行时静默/主动捕获所有输出
  3. '跳进去'在任何时候检查整个输出的内容?
  4. 上面的python脚本是我对捕获输出感兴趣的一种过程的模型,即有一个无限循环,每秒打印一次输出;正是这个输出我对积极监控/捕获感兴趣。

1 个答案:

答案 0 :(得分:0)

这是一个在另一个线程上打开进程的实现(因此您不必阻塞主线程)并使用Queue回传线路。使用Event

按需要杀死该线程
#!/usr/bin/env python

from subprocess import Popen, PIPE
from threading import Thread, Event
from Queue import Queue
from time import sleep

# communicates output lines from process to main thread
lines = Queue()
# kills thread
kill = Event()


def runner():
    p = Popen(["python", "multiply.py"], stdout=PIPE)
    # to get stream behaviour
    while p.poll() is None and not kill.isSet():
        lines.put(p.stdout.readline())

    p.kill()
    # in your use case this is redundant unless the process
    # is terminated externally - because your process is never done
    # after process finished some lines may have been missed
    if not kill.isSet():
        for line in p.stdout.readlines():
            lines.put(line)

# open process on another thread    
t = Thread(target=runner)
t.start()

# do stuff - lines aggregated on the queue    
print "First run"
sleep(1)
while not lines.empty():
    print lines.get()

# move to more important stuff...
sleep(3)

# now check the output we missed
print "Second run"
while not lines.empty():
    print lines.get()

# done doing stuff

# tell thread to kill itself
kill.set()
# wait for thread
t.join()
print "done"