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

时间:2014-12-20 00:53:46

标签: windows node.js terminal

我试图在Windows上使用node.js将一个ANSI转义序列写入stdout,但它似乎不起作用。

具体来说,我使用ConEmu support子集ANSI代码。我创建了一个应该重命名当前控制台选项卡的测试文件:

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

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

为什么逃脱序列不起作用?

1 个答案:

答案 0 :(得分:5)

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

但是,当节点连接到Windows中的交互式终端时,它(通过libuv)实际上parses all ANSI escape codes,以便它可以使用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转义码的终端模拟器。)


为了更好地实现我的特定目的,我最终编写了一个模块 - console-title - 通过在unix上编写ANSI转义序列来更改控制台的标题,并在Windows下调用appropriate native API。这允许我在Windows的默认控制台窗口和ConEmu等模拟器中更改标题。