自定义tee命令丢失控制台颜色序列问题及修复需求
修复批处理TEE工具丢失ANSI颜色输出的问题
我找到一个能同时在控制台显示内容并写入文件的TEE方案,但使用后原本正常的ANSI颜色转义序列失效了——控制台直接显示[91m这类转义码,而非彩色文本。怀疑是JScript写入stdout的方式导致,但不知如何修复。理想效果是控制台显示彩色输出,日志文件可去除转义序列;退一步,转义序列保留在文件中也可接受。
原代码如下:
@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment ::--- Batch section within JScript comment ---------------------------- @echo off ::This block of code handles the TEE by calling the internal JScript code if "%~1"=="_TEE_" ( cscript //E:JScript //nologo "%~f0" %2 %3 exit /b ) ::The rest of your batch script goes here ::This pipes to TEE in append mode echo This will be [91mColoured[0m echo This will not be [91mColoured[0m and just shows the escapes | "%~f0" _TEE_ output.txt 1 pause ----- End of JScript comment, beginning of normal JScript ------------------*/ var fso = new ActiveXObject("Scripting.FileSystemObject"); var mode=2; if (WScript.Arguments.Count()==2) {mode=8;} var out = fso.OpenTextFile(WScript.Arguments(0),mode,true); var chr; while( !WScript.StdIn.AtEndOfStream ) { chr=WScript.StdIn.ReadAll(); WScript.StdOut.Write(chr); out.Write(chr); }
问题根源
cscript默认以纯文本模式输出,转义序列会被原样输出而不被控制台解析;同时管道传输时,批处理的stdout变为非交互式流,ANSI转义的解析也会受影响。
方案1:保留文件转义序列,恢复控制台彩色
给cscript添加//U参数,让它以Unicode模式输出,确保转义序列完整传递给控制台。
修改批处理中的TEE调用部分:
if "%~1"=="_TEE_" ( cscript //U //E:JScript //nologo "%~f0" %2 %3 exit /b )
注意:Windows 10 1511及以上版本默认支持ANSI转义,旧系统需手动开启
HKCU\Console\VirtualTerminalLevel注册表项(设为1)。
方案2:控制台彩色显示,文件去除转义序列
若需要日志文件无转义码,可在JScript中分离处理:输出控制台时保留转义,写入文件时移除所有ANSI转义序列。
修改后的完整代码:
@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment ::--- Batch section within JScript comment ---------------------------- @echo off ::This block of code handles the TEE by calling the internal JScript code if "%~1"=="_TEE_" ( cscript //U //E:JScript //nologo "%~f0" %2 %3 exit /b ) ::The rest of your batch script goes here ::This pipes to TEE in append mode :: 注意:正确的ANSI转义码需要用^[(Alt+027输入),而非直接写[91m echo This will be ^[[91mColoured^[[0m echo This will be ^[[91mColoured^[[0m and file has no escapes | "%~f0" _TEE_ output.txt 1 pause ----- End of JScript comment, beginning of normal JScript ------------------*/ var fso = new ActiveXObject("Scripting.FileSystemObject"); var mode=2; if (WScript.Arguments.Count()==2) {mode=8;} var out = fso.OpenTextFile(WScript.Arguments(0),mode,true); var content; while( !WScript.StdIn.AtEndOfStream ) { content = WScript.StdIn.ReadAll(); // 输出到控制台,保留转义序列 WScript.StdOut.Write(content); // 移除所有ANSI转义序列后写入文件 var cleanContent = content.replace(/\x1b\[[0-9;]*m/g, ''); out.Write(cleanContent); }
关键说明
//U参数确保转义序列不被破坏,控制台能正确解析彩色。- 正则
/\x1b\[[0-9;]*m/g匹配所有ANSI颜色转义序列,替换为空即可清除。 - 原代码中的
[91m是错误写法,实际批处理中需用^[(按住Alt+027输入)来表示转义字符\x1b。
内容的提问来源于stack exchange,提问作者Hugoagogo
相关产品推荐
相关产品推荐

