如何在存储控制台的实时输出的同时运行 python 脚本?



我想创建一个函数来执行python脚本,同时在执行时实时存储控制台输出。

例如,我使用子进程模块运行 example.py,但我只在整个脚本运行后接收控制台输出,而不是在发生时获取控制台输出。换句话说,按照下面的脚本,我想立即接收控制台输出"hello world",然后等待 60 秒,然后接收控制台输出"再见世界">

example.py

import time 
print "hello world!"
time.sleep(60)
print "goodbye world"

下面是在 example.py 中运行脚本并在之后存储控制台的脚本

import subprocess
script = open('example.py',"r+").read()
process = subprocess.Popen(['python', '-'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process.stdin.write(script)
stored_console_output, stored_console_output_error = process.communicate()
print stored_console_output

这将在整个脚本执行后以字符串形式返回以下内容

hello world!
goodbye world

注意:我无法更改 python 脚本 example.py。我只能更改调用它的函数。

除了实时获取控制台输出(如果可能(之外,我还想获取导致该控制台输出的 python 行。例如,我想获得以下

import time 
print "hello world!"
hello world
time.sleep(60)
print "goodbye world"
goodbye world

我也尝试使用 sys 模块,但它不存储控制台输出:

import sys
import inspect
class SetTrace(object):
def __init__(self, func):
self.func = func
def __enter__(self):
sys.settrace(self.func)
return self
def __exit__(self, ext_type, exc_value, traceback):
sys.settrace(None)
def monitor(frame, event, arg):
if event == "line":
print event
return monitor

with SetTrace(monitor):
exec(open('example.py',"r+").read())

这将返回以下内容,并实时执行。

line
line
line
hello world!
line
line
goodbye world
line

这篇文章在很大程度上回答了你的问题,尽管有一条评论特别为你的特定问题提供了关键:调用example.py时你需要-u标志,以防止sleep()上的STDOUT缓冲。

大量借用上述答案,此解决方案有效:

from subprocess import Popen, PIPE
def execute(cmd):
popen = Popen(cmd, stdout=PIPE, universal_newlines=True)
for stdout_line in iter(popen.stdout.readline, ""):
yield stdout_line 
popen.stdout.close()
for statement in execute(['python', '-u', 'example.py']):
print(statement, end="")

输出:

Hello
# pauses for the number of sleep seconds
Goodbye

最新更新