Windows 10环境Git Bash中Julia调用Base.run后ANSI颜色失效问题咨询
问题成因
- Windows平台默认控制台对ANSI转义序列的支持依赖控制台模式的
ENABLE_VIRTUAL_TERMINAL_PROCESSING标识,Julia启动时会自动为标准输出开启该标识,但调用Base.run执行Git for Windows自带的MSYS2工具链程序(比如true)时,MSYS2程序会在退出前重置控制台模式,意外关掉了虚拟终端处理标识,导致后续Julia输出的ANSI转义序列不会被解析,直接显示为原始字符。 - 调用cmd原生命令不会触发该问题的原因是cmd原生程序不会修改控制台的虚拟终端处理标识,所以Julia初始设置的模式不会被破坏。Python没有该问题是因为Python每次输出前都会重新检查并开启虚拟终端处理标识,1.8以下版本的Julia没有做这个容错处理。
解决方案
- 手动重置控制台虚拟终端处理标识
每次调用run执行MSYS2程序后,主动调用Windows API重新开启标识,代码示例:
const ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 if Sys.iswindows() function reset_ansi_support() # 获取标准输出句柄 handle = ccall(:GetStdHandle, Ptr{Cvoid}, (UInt32,), 0xFFFFFFF5) mode = Ref{UInt32}(0) ccall(:GetConsoleMode, Cint, (Ptr{Cvoid}, Ptr{UInt32}), handle, mode) # 开启虚拟终端处理标识 mode[] |= ENABLE_VIRTUAL_TERMINAL_PROCESSING ccall(:SetConsoleMode, Cint, (Ptr{Cvoid}, UInt32), handle, mode[]) end end # 使用示例 run(`true`) reset_ansi_support() println("\33[1;31mhello\33[0m")
- 升级Julia版本
该问题已经在Julia 1.8及以上版本修复,新版本Julia在每次输出到控制台前都会主动检查虚拟终端处理标识状态,被外部程序重置后会自动恢复,升级到最新稳定版即可直接解决。 - 临时规避方案
如果暂时不能升级Julia,涉及调用MSYS2程序的场景可以用run(pipeline(true, stdout=devnull, stderr=devnull))的方式执行,部分场景下可以避免MSYS2程序修改当前控制台模式。
内容的提问来源于stack exchange,提问作者Geoff
相关产品推荐
相关产品推荐

