使用Python读取在进程运行时的命令行输出

17 浏览
0 Comments

使用Python读取在进程运行时的命令行输出

似乎有很多种方法可以通过使用Python的命令行来调用系统进程,并在进程完成后读取输出。例如,subprocess模块可以通过subprocess.Popen(['ls'])实现这一点。是否有一种方式可以在进程运行时读取输出?

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

import time
def multiply(a,b):
    newA = a
    newB = b
    while True: #无限循环
        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. 在任何时候都可以“插入”并查看整个输出的内容?

上述Python脚本是我有兴趣捕获输出的过程类型的模型,即有一个无限循环,每秒打印一次输出;我有兴趣主动监控/捕获这个输出。

0
0 Comments

使用Python读取命令行输出的问题通常出现在需要在调用的进程仍在运行时读取命令行输出的情况下。下面是一个解决该问题的实现方法:

首先,我们在另一个线程上打开进程,这样可以避免阻塞主线程,并使用一个队列(Queue)将输出行传递回主线程。通过使用一个事件(Event),我们可以在需要时杀死线程。

具体的实现代码如下所示:

#!/usr/bin/env python
from subprocess import Popen, PIPE
from threading import Thread, Event
from Queue import Queue
from time import sleep
# 用于在进程和主线程之间传递输出行
lines = Queue()
# 用于杀死线程
kill = Event()
def runner():
    p = Popen(["python", "multiply.py"], stdout=PIPE)
    # 获取流式输出
    while p.poll() is None and not kill.isSet():
        lines.put(p.stdout.readline())
    p.kill()
    
    # 在你的使用情况下,除非进程被外部终止,否则这是多余的
    # 因为你的进程永远不会结束
    # 在进程结束后,可能会丢失一些输出行
    if not kill.isSet():
        for line in p.stdout.readlines():
            lines.put(line)
# 在另一个线程上打开进程
t = Thread(target=runner)
t.start()
# 执行其他任务 - 输出行保存在队列中
print "开始执行"
sleep(1)
while not lines.empty():
    print lines.get()
# 进行更重要的任务...
sleep(3)
# 现在检查我们之前错过的输出
print "继续执行"
while not lines.empty():
    print lines.get()
# 完成任务
# 告诉线程自行终止
kill.set()
# 等待线程结束
t.join()
print "完成"

感谢你的回复。我如何在特定的时间检查命令行输出?这段代码运行了大约4分钟,但没有输出任何命令行输出。

你可以在任何你认为合适的时间消耗队列。如果你想在特定的时间获取输出,你可以为每个元素附加一个读取时间戳,并在队列中创建元组,例如`lines.put((time.time(), p.stdout.readline(),))`。请确保从`time`模块中导入`time`。如果你有其他期望,请更新你的问题以提供更具体的信息。

0