如何在使用subprocess.Popen时保留在终端中输出的原始颜色编码?

4

我有一个简单的 Python 脚本,可以实时打印出命令的输出。以下是该脚本:

#!/usr/bin/env python3
import subprocess

def RunSubProcess(process, process_args):
    process = subprocess.Popen([process, process_args], 
                               stdout=subprocess.PIPE, 
                               stderr=subprocess.PIPE, 
                               universal_newlines=True)
    while process.stdout.readable():
        line = process.stdout.readline()
        if not line:
            break
        print(line.strip())

RunSubProcess('ls', '-la')

这个脚本执行得很好,但是它会失去我的Shell的输出颜色编码。如果我输入ls -la,我可以得到彩色输出。但如果我运行上面的Python脚本,它会不保留颜色。

subprocess.Popen是否有一个参数能够保留它所在的Shell的颜色编码呢?

PS:
我正在MacOS上的bash shell上运行这个Python脚本,使用的是Python 3.9.0。

2个回答

2
许多程序会检测它们是否连接到终端,并切换到不同的交互式使用行为。
有些提供选项来强制启用交互式功能(尝试使用ls --color=always,但实际效果取决于您的平台;这不是标准化的行为。 macOS ls man page 建议在环境中设置CLICOLOR=yes),而其他程序则可以通过使用pty库或更高级别的pexpect欺骗其以为正在交互式运行,并且有些更易于使用。

1
通常情况下,您应该避免在脚本中使用ls,但我猜您是将其用作示例。 - tripleee
1
是的,ls只是一个示例,用来说明我的问题。 - TheWaterProgrammer
1
能否将stderr的输出仅以红色进行着色?这是可能的。我应该尝试在那个print调用中做一些技巧。 - TheWaterProgrammer
1
你可以在Python端轻松地为标准错误添加颜色代码。当然,你必须从你的subprocess调用中捕获它。 - tripleee

1

这个方法对我来说很有效,并且保持了颜色。

               cmd = "/bin/ls -l --color"

               # Run command. Print output in real-time. Maintain text colors.                                                                                
                proc = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)                                                                              
                for line in iter(proc.stdout.readline, ""):                                                                                                    
                    line = line.decode("utf-8")                                                                                                                
                    if line == "":                                                                                                                             
                        break                                                                                                                                  
                    print(line.rstrip())                                                                                                                       
                rc = proc.poll()                                                                                                                               
                while rc is None:                                                                                                                              
                    time.sleep(0.1)                                                                                                                            
                    rc = proc.poll()             

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接