Python子进程,实时打印颜色并保存标准输出 [英] Python subprocess, realtime print with COLORS and save stdout

查看:37
本文介绍了Python子进程,实时打印颜色并保存标准输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在保存结果的同时打印子进程的输出并不是一个新问题,之前已经多次回答过例如:https://stackoverflow.com/a/28319191/5506400这对我不起作用,因为我试图保持打印的外壳颜色.例如.当一个去systemctl status application时,它的打印件以绿色运行.上述方法都依赖于从子进程中逐行读取,但在我看来,它们的颜色信息被剥离并丢失了.

Printing the output of a subprocess while saving the result is not a new problem, and has been answered many times before e.g.: https://stackoverflow.com/a/28319191/5506400 This does not work for me because I am trying to maintain the shell colours printed. E.g. when one goes systemctl status application, its prints running in green. The above-mentioned methods all rely on reading a line one by one from subprocess, but it seems to me by them the colour information is stripped off and lost.

我试图制作一个脱离标准输出打印的对象,并将它们保存到一个变量中:

I tried to make an object which tee's off the stdout prints and saves them into a variable:

from subprocess import *
import sys

class Tee():
    def __init__(self):
        self.content = ''
        self.stdout = sys.stdout
        sys.stdout = self
    def __enter__(self):
        return self
    def __exit__(self, *args):
        pass
    def __del__(self):
        sys.stdout = self.stdout
    def write(self, data):
        self.content += data
        self.stdout.write(data)
    def flush(self):
        self.content = ''

with Tee() as tee:
    # Saves print to tee.content
    print("Hello World")

    # This line does not save prints to tee.content    
    run(['apt-get', 'update'])

    # raises an error that tee.fileno is not supported
    run(['systemctl', 'status', 'nginx'], stdout=tee)

    content = tee.content

print("---------------------")
print(content)

但问题是子进程的标准输出需要一个实际文件:https://stackoverflow.com/a/2298003/5506400

But the problem is subprocess's stdout requires an actual file: https://stackoverflow.com/a/2298003/5506400

有没有办法实时打印子进程的输出,同时保持颜色,并将值存储到变量中(不通过临时文件)?

Is there anyway to print realtime the output of a subprocess, while maintaining the colours, and store the value to a variable (without going through a temp file)?

推荐答案

systemctl 检查输出的去向;如果是 tty,则显示彩色输出.如果 STDOUT 未附加到 tty,则不会显示颜色.

systemctl checks where the output is going; if it's a tty, it shows colorized output. If the STDOUT is not attached to a tty, it does not show the color.

因此,本质上您需要从源代码执行此操作,即当 STDOUT 不是 tty 时,让 systemctl 发出必要的转义码.

So, essentially you need to do this from source i.e. make systemctl emit necessary escape codes when the STDOUT is not a tty.

有一种方法,来自man systemd:

$SYSTEMD_COLORS
    Controls whether colorized output should be generated.

因此您需要传递SYSTEMD_COLORS 环境变量以使systmectl 返回带有颜色转义的输出.

So you need to pass the SYSTEMD_COLORS environment variable to make systmectl return output with color escapes.

你可以这样做:

os.environ['SYSTEMD_COLORS'] = '1'
subprocess.run(['systemctl', 'status', 'application'], stdout=subprocess.PIPE)

要让这个命令的 env var 只在之后执行 del os.environ['SYSTEMD_COLORS'].

To have the env var for this command only do del os.environ['SYSTEMD_COLORS'] afterwards.

或者直接在 shell 上运行仅用于单个命令:

Or run on shell directly for single command only:

subprocess.run('SYSTEMD_COLORS=1 systemctl status application', shell=True, stdout=subprocess.PIPE)

这篇关于Python子进程,实时打印颜色并保存标准输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆