繁体   English   中英

Python子进程,实时打印颜色并保存标准输出

[英]Python subprocess, realtime print with COLORS and save stdout

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

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

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

无论如何要实时打印子进程的输出,同时保持颜色,并将值存储到变量(不通过临时文件)?

systemctl检查输出的systemctl 如果是 tty,则显示彩色输出。 如果 STDOUT 未连接到 tty,则不会显示颜色。

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

有一种方法,来自man systemd

$SYSTEMD_COLORS
    Controls whether colorized output should be generated.

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

你可以做:

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

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

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

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

你不能用subprocess ,但pty可以。 pty创建伪终端,以便正在执行的命令检测到它正在运行 tty 并启用颜色输出。

import pty, os

output_bytes = []

def read(fd):
    data = os.read(fd, 1024)
    output_bytes.append(data)
    return data

pty.spawn([command], read)
output = str(output_bytes)
# parse output as you need

暂无
暂无

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

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