使用Popen获取带有颜色的文本输出

8
我正在使用popen制作插件,该插件使用外部程序在输出中显示一些带颜色的文本。
输出类似于以下内容:
avr-g++ -o .pioenvs\uno\FrameworkArduino\HardwareSerial.o -c -std=gnu++11 -fno-exceptions -fno-threadsafe-statics -g -Os -Wall -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO_AVR_UNO -DARDUINO=10607 -I.pioenvs\uno\FrameworkArduino -I.pioenvs\uno\FrameworkArduinoVariant .pioenvs\uno\FrameworkArduino\HardwareSerial.cpp    
avr-g++ -o .pioenvs\uno\FrameworkArduino\HardwareSerial0.o -c -std=gnu++11 -fno-exceptions -fno-threadsafe-statics -g -Os -Wall -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO_AVR_UNO -DARDUINO=10607 -I.pioenvs\uno\FrameworkArduino -I.pioenvs\uno\FrameworkArduinoVariant .pioenvs\uno\FrameworkArduino\HardwareSerial0.cpp
=============================================
Path\file.cpp: in function 'void loop()':
Path\file.cpp:23:2 error: expected ';' before '}' token
}
^
=============================================

所有在 "=" 内的内容都是红色和黄色。

当我在命令控制台中运行命令时,我可以看到完整的输出,但是当我使用 Popen 时,我只能得到未着色的文本。

这是我使用 Popen 的方式:

process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=self.cwd, universal_newlines=True, shell=True)
output = process.communicate()

stdout = output[0]
stderr = output[1]

print(stdout)
print(stderr)

即使文本没有颜色,我也希望能够获取完整的日志。欢迎提供任何建议。


如果我的回答有助于解决您的问题,请点赞支持我。 :) - ‌‌R‌‌‌.
完成!再次感谢 :) - GEPD
2个回答

4
您无法获取所有消息,因为您的命令输出的一部分不是常规输出,而被视为错误(或日志或调试消息)。
现在,您可以将 stderr=subprocess.PIPE 添加到您的 Popen 参数中,这将把所有错误放入您的 stderr 变量中:
process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.cwd, universal_newlines=True, shell=True)
output = process.communicate()

stdout = output[0]
stderr = output[1]

print(stdout)
print(stderr)

如果您想要在命令行中看到所有的错误和输出信息,就像在控制台中看到的那样,可以在命令的末尾添加2>&1。例如:

avr-g++ -o .pioenvs\uno\FrameworkArduino\HardwareSerial.o -c -std=gnu++11 -fno-exceptions -fno-threadsafe-statics -g -Os -Wall -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO_AVR_UNO -DARDUINO=10607 -I.pioenvs\uno\FrameworkArduino -I.pioenvs\uno\FrameworkArduinoVariant .pioenvs\uno\FrameworkArduino\HardwareSerial.cpp 2>&1

1
谢谢@Rahman,您的最后一个建议解决了我的问题。您有关于该解决方案的阅读链接吗?或者您能解释一下2>&1的含义吗? - GEPD
3
@GEPD 这是我在回答你之前阅读的链接 https://dev59.com/Z3RA5IYBdhLWcg3wzhXZ#818284 - ‌‌R‌‌‌.
3
要了解如何保留颜色代码,可以查看avr-g++手册中的-fdiagnostics-color[=WHEN]部分。请注意,不要改变原来的意思,并尽可能使翻译更加通俗易懂。 - PM 2Ring
谢谢@PM2Ring,我现在会看一下,虽然我没有直接使用avr-g++,但了解这些额外的信息还是很好的。 - GEPD

3

当我在命令控制台中运行命令时,我可以看到完整的输出,但是当我使用Popen时,我只能得到未着色的文本。

可能有两个问题:

  1. the colored text happens to be produced on stderr, not stdout. To capture stderr, set stderr=PIPE, as @Rahman suggested

  2. avr-g++ command may disable colors if it detects that the output is not a tty e.g., if it is redirected to a pipe like in your case. To enable colors, pass the command-line option -fdiagnostics-color=always as @PM 2Ring suggested.

    Or (less portable but it may work with more commands) provide a pseudo-tty to hoodwink the avr-g++ command into thinking that it runs interactively (and therefore it should enable colors). You could do it using pty.spawn(), pexpect module:

    import pexpect # $ pip install pexpect
    
    output, exitstatus = pexpect.runu(command, withexitstatus=1)
    

    or (more low-level) using pty.openpty() + subprocess module.


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