我为我的应用程序编写了一个简单的python脚本,并预定了一些快速命令,如make等。
我编写了一个运行系统命令的函数(linux):
def runCommand(commandLine):
print('############## Running command: ' + commandLine)
p = subprocess.Popen(commandLine, shell = True, stdout = subprocess.PIPE)
print (p.stdout.read().decode('utf-8'))
除了一些事情之外,一切都很顺利:
我正在使用 cmake 并且它的输出是彩色的。有没有机会在输出中保存颜色?
我可以在流程完成后查看输出。例如, make 运行很长一段时间但我只能在完全编译后看到输出。如何异步进行?
答案 0 :(得分:12)
我不确定颜色,但是这里是如何一次轮询子进程的stdout一行:
import subprocess
proc = subprocess.Popen('cmake', shell=True, stdout=subprocess.PIPE)
while proc.poll() is None:
output = proc.stdout.readline()
print output
不要忘记从stderr读取,因为我确信cmake会在那里发出信息。
答案 1 :(得分:4)
你没有获得颜色,因为cmake
检测到它的标准输出是否是一个终端,如果不是它没有为自己的输出着色。某些程序为您提供强制着色输出的选项。不幸的是cmake
没有,所以你在那里运气不好。除非您想自己修补cmake
。
许多程序都这样做,例如grep:
# grep test test.txt
test
^
|
|------- this word is red
现在将它传递给cat:
# grep test test.txt | cat
test
^
|
|------- no longer red
grep
选项--color=always
强制使用颜色:
# grep test test.txt --color=always | cat
test
^
|
|------- red again
答案 2 :(得分:2)
关于如何在流程完成之前获取流程的输出,应该可以替换:
p.stdout.read
使用:
for line in p.stdout:
关于如何保存彩色输出,没有什么特别之处。例如,如果行输出保存到文件中,则下次执行cat <logfile>
时,控制台将解释转义序列并按预期显示颜色。
答案 3 :(得分:1)
对于CMake,您可以使用选项CLICOLOR_FORCE=1
强制颜色输出:
command = 'make CLICOLOR_FORCE=1'
args = shlex.split(command)
proc = subprocess.Popen(args, stdout=subprocess.PIPE)
然后按照accepted answer:
进行打印while proc.poll() is None:
output = proc.stdout.readline()
print(output.decode('utf-8'))
如果在打印前解码为utf-8,则应看到彩色输出。 如果您将结果打印为字节文字(即不解码),您应该看到各种颜色的转义序列。
考虑尝试选项universal_newlines=True
:
proc = subprocess.Popen(args, stdout=subprocess.PIPE, universal_newlines=True)
这会导致对proc.stdout.readline()
的调用返回字符串而不是字节文字,因此您可以/必须跳过对decode()
的调用。
答案 4 :(得分:0)
要执行异步输出,请执行以下操作:http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440554
不确定是否可以捕获彩色输出。如果你可以获得转义的颜色代码,你可以。
答案 5 :(得分:-1)
这里值得注意的是使用script
命令作为伪终端并被检测为tty而不是重定向(管道)文件描述符,请参阅:
bash command preserve color when piping
像魅力一样......
根据问题中的示例,只需让script
执行cmake
:
import subprocess
proc = subprocess.Popen('script cmake', shell=True, stdout=subprocess.PIPE)
while proc.poll() is None:
output = proc.stdout.readline()
print output
这使得cmake
认为它正在从终端执行并且会产生你所追求的ANSI糖果。
的nJoy!