ANSI转义序列不会打印到Windows上的stdout

我想在Windows上使用node.js写一个ANSI转义序列到stdout,但它似乎不工作。

具体来说,我使用支持 ANSI代码的ConEmu 。 我创build了一个应该重命名当前控制台选项卡的testing文件:

process.stdout.write('\x1b]9;3;"abc"\x1b\x5c'); 

然而,当我运行它时没有任何反应。 如果我运行node test > out.txt ,正确的字节被写入输出文件。

为什么转义序列不起作用?

当节点的标准输出连接到非交互式接收器(即管道或重定向到文件)时,写入到process.stdout字节将按原样写入。 因此,运行node test > out.txt会产生预期的结果。

但是,当节点连接到Windows中的交互式终端时,它(通过libuv)实际上会解析所有ANSI转义码,以便它可以透明地模拟使用Windows API的unix TTY终端。 这是因为Windows控制台不支持ANSI转义序列,所以会使颜色和重新定位光标在Windows中工作。

未知和不受支持的序列将被忽略。

因此,JS调用process.stdout.write()WriteConsoleW() (其中节点实际输出到终端)的内部调用之间会丢弃任何无法识别的命令。

这可以通过在fd 1上打开原始文件系统流从用户代码中解决。

 var rawStdout = new fs.SyncWriteStream(1, { autoClose: false }); 

将ANSI转义序列写入rawStdout将正确发送到终端。

 rawStdout.write('\x1b]9;3;"abc"\x1b\x5c'); 

(当然,这不会给Windows控制台带来任何神奇的新功能,它只是简单地打印序列,看起来像垃圾,实际上你必须使用某种支持ANSI转义码的终端仿真器。


为了更好地实现我的特定目标,我最终编写了一个模块 – 控制台标题 – 通过在UNIX上编写ANSI转义序列来更改控制台的标题,并在Windows下调用相应的本机API 。 这允许我在Windows的默认控制台窗口和仿真器如ConEmu中更改标题。