You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Python subprocess调用PowerShell时,保留Write-Host输出颜色至文件

问题描述

我通过Python的subprocess在同一个PowerShell会话中连续执行多个命令(比如先定义函数再调用),部分命令使用带-ForegroundColor参数的Write-Host cmdlet,希望保留这种写法。我把PowerShell会话的输出重定向到文件,想保留-ForegroundColor设置的颜色,后续在PowerShell中读取该文件时能显示带颜色的完整输出,但目前无法将颜色代码写入文件。

最小可复现示例:

from subprocess import Popen, PIPE, call
import time

print("\n\ncoloring in the terminal works:")
print("--------------------------")
time.sleep(1)
process = Popen(['powershell.exe'], stdin=PIPE)
process.stdin.write(b'Write-Host -ForegroundColor Red "TEST"\r\n')
process.stdin.flush() 
process.stdin.close()  

time.sleep(1)

print("\n\ncoloring when writing to a file and reading output from that file again")
print("------------------------------------------------------------------------")
with open('./out.txt', 'wb') as f:    
    process = Popen(['powershell.exe'], stdin=PIPE, stdout=f)
    process.stdin.write(b'Write-Host -ForegroundColor Red "TEST"\r\n')
    process.stdin.flush() 
    process.stdin.close()   

time.sleep(1)
call(['powershell.exe', 'cat', './out.txt'])

print("\n\n---------------")
print("and we're done.\n")
解决方案

要保留Write-Host的颜色代码到文件,需要解决两个核心问题:

  • Write-Host的输出默认走信息流(编号6),而非标准输出(stdout),直接重定向stdout无法捕获;
  • PowerShell检测到输出目标不是终端时,会自动禁用颜色输出,需要强制启用ANSI颜色渲染。

具体步骤

  1. 强制PowerShell输出ANSI颜色代码:在执行Write-Host前,设置$PSStyle.OutputRendering = 'Ansi'(适用于PowerShell 7+;若使用PowerShell 5.1,需确保系统启用ANSI支持,推荐优先升级到PowerShell 7)。
  2. 将信息流重定向到标准输出:在Write-Host命令末尾添加6>&1,把信息流的内容转发到stdout,这样就能被文件句柄捕获。

修改后的Python代码示例

from subprocess import Popen, PIPE, call
import time

print("\n\ncoloring in the terminal works:")
print("--------------------------")
time.sleep(1)
process = Popen(['powershell.exe'], stdin=PIPE)
process.stdin.write(b'Write-Host -ForegroundColor Red "TEST"\r\n')
process.stdin.flush() 
process.stdin.close()  

time.sleep(1)

print("\n\ncoloring when writing to a file and reading output from that file again")
print("------------------------------------------------------------------------")
with open('./out.txt', 'wb') as f:    
    process = Popen(['powershell.exe'], stdin=PIPE, stdout=f)
    # 先设置强制输出ANSI颜色,再执行Write-Host并转发信息流到stdout
    cmd = b'$PSStyle.OutputRendering = "Ansi"; Write-Host -ForegroundColor Red "TEST" 6>&1\r\n'
    process.stdin.write(cmd)
    process.stdin.flush() 
    process.stdin.close()   

time.sleep(1)
call(['powershell.exe', 'cat', './out.txt'])

print("\n\n---------------")
print("and we're done.\n")

补充说明

  • 如果需要在同一个会话中执行多步操作(比如定义函数后调用),只需把所有命令按顺序用分号分隔组合即可,示例:
    $PSStyle.OutputRendering = "Ansi"; function Test-Color { Write-Host -ForegroundColor Green "Hello" 6>&1 }; Test-Color
    
  • 后续用PowerShell的cat(即Get-Content)读取文件时,会自动解析ANSI转义码并显示对应颜色。

内容的提问来源于stack exchange,提问作者schtopps

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 06:02:09