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

标签 python console subprocess trace sys

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

例如,我使用 subprocess 模块来运行 example.py,但我仅在整个脚本运行后才收到控制台输出,而不是在发生时获取控制台输出。换句话说,根据下面的脚本,我想立即接收控制台输出“hello world”,然后等待60秒,然后接收控制台输出“goodbye world”

示例.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

最佳答案

This post很大程度上回答了你的问题,尽管有 one comment特别是它提供了解决您的特定问题的关键:调用 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

关于python - 如何在存储控制台实时输出的同时运行 python 脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45527115/

相关文章:

python - Twine 不允许我注册或上传我的包裹 : is https://upload. pypi.org/legacy/wrong?

sql - 禁用 Rails 3.2.1 控制台 SQL 日志记录

c# - 增加和减少混淆

python - subprocess.popen() stderr 重定向与管道/失败

python - 如何通过子进程将带有空格的参数传递给 bash?

python - Selenium 查找按钮元素

python - 获取 admin_only 装饰器的重定向循环

Python 列表到 Django 数据库表

java - 无法使用 Eclipse 从 java 控制台读取值

Python:使用 Pool、apply_async 和 join