【问题标题】:Using python to read command line output while invoked process is still running [duplicate]在调用的进程仍在运行时使用python读取命令行输出[重复]
【发布时间】:2015-02-19 05:31:01
【问题描述】:

似乎有很多方法可以使用 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. 'jump in'随时查看整个输出的内容?

上面的 python 脚本是我对捕获输出感兴趣的那种过程的模型,即有一个无限循环,它每秒打印一个输出;我对主动监控/捕获感兴趣的是这个输出。

【问题讨论】:

  • 尝试了这些建议:他们没有解决问题
  • “他们没有解决问题” 信息量不是很大。请edit您的问题并准确说明您的情况有何不同:当您从重复问题运行解决方案时会发生什么?你期望会发生什么?提及您如何运行脚本(操作系统、Python 版本、IDE 或终端应用程序)。我假设您可以自己进行一些小的修改,例如entire_output.append(line)

标签: python subprocess


【解决方案1】:

这是一个在另一个线程上打开进程的实现(因此您不必阻塞主线程)并使用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"

【讨论】:

  • 感谢您的回复。我将如何使用它在特定时间检查命令行输出?代码运行了约 4 分钟,没有输出任何命令行输出。
  • @Ryan 您可以在任何您认为合适的时候使用队列。如果您想要在特定时间输出,您可以将读取时间戳附加到每个元素并在队列中创建元组,例如lines.put((time.time(), p.stdout.readline(),))。确保从time 导入time。如果您期望其他内容,请更新您的问题以更具体。
猜你喜欢
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 2021-04-03
  • 2018-08-13
  • 2013-01-25
  • 1970-01-01
  • 2019-02-28
  • 2014-07-18
相关资源
最近更新 更多