繁体   English   中英

实时打印 stderr 和 stdout 的子进程

[英]subprocess to print stderr and stdout in real-time

提示:本站提供中英文对照查看,鼠标放在中文字句上可显示英文原文。 若本文未解决您的问题,推荐您尝试使用帮您解决。

假设我有这个程序printer.py

#!/usr/bin/env python3

import sys
import time

sys.stdout.write("STDOUT 1\n")
time.sleep(1)
sys.stderr.write("STDERR 2\n")
time.sleep(1)
sys.stdout.write("STDOUT 3\n")
time.sleep(1)
sys.stderr.write("STDERR 4\n")
time.sleep(1)

它打印到 stdout 和 stderr 以产生:

./printer.py 
STDOUT 1
STDERR 2
STDOUT 3
STDERR 4

我想在另一个 python 脚本runner.py中执行printer.py ,并实时打印 stderr 和 stdout。 以下版本的runner.py不起作用:

#!/usr/bin/env python3

import sys
import subprocess

def run_command(command):
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
    while True:
        output = process.stdout.readline().decode()
        if output == '' and process.poll() is not None:
            break
        if output:
            print(output.strip())
    rc = process.poll()
    return rc

rc = run_command('./printer.py')

因为它首先实时打印 stderr 行,然后同时打印 stdout 行:

./runner.py 
STDERR 2
STDERR 4
STDOUT 1
STDOUT 3

如何修复它以实时获得正确的顺序 1、2、3 和 4? 我能得到的更接近的是使用:

rc = run_command('./printer.py 1>&2')

这有点好,但我想知道我是否可以让它做正确的事情并以与printer.py相同的方式打印到 stdout 和 stderr。


评论中建议的sys.stdout.flush()没有区别:

#!/usr/bin/env python3

import sys
import subprocess

def run_command(command):
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
    while True:
        output = process.stdout.readline().decode()
        if output == '' and process.poll() is not None:
            break
        if output:
            sys.stdout.write(output.strip() + '\n')
            sys.stdout.flush()
    rc = process.poll()
    return rc

rc = run_command('./printer.py')
./runner.py 
STDERR 2
STDERR 4
STDOUT 1
STDOUT 3

print(..., flush=True)相同。 难道我做错了什么?

我正在整理评论并添加一些我的意见。 感谢@Barmar 和@MarkSetchell。

最后,我想我会寻求以下解决方案:

rc = run_command('PYTHONUNBUFFERED=1 ./printer.py')

它应该与@MarkSetchell 的python -u./printer.py 但是,为此我会明确设置printer.py的路径,我宁愿避免这样做。 但我还不确定每一个的优缺点。

unbuffer解决方案:在我的 Ubuntu 上没有安装 18,所以我宁愿避免额外的依赖。 据我了解,我会将其用作rc = run_command('unbuffer./printer.py')

编辑printer.py对我来说不是一个选项,否则在每次printsys.stdout.write之后添加sys.stdout.flush()也应该有效。

问题未解决?试试使用:帮您解决问题。
暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2023 STACKOOM.COM