[英]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.