我试图在Windows上使用node.js将一个ANSI转义序列写入stdout,但它似乎不起作用。
具体来说,我使用ConEmu support子集ANSI代码。我创建了一个应该重命名当前控制台选项卡的测试文件:
process.stdout.write('\x1b]9;3;"abc"\x1b\x5c');
然而,当我运行它时没有任何反应。如果我运行node test > out.txt
,则将正确的字节写入输出文件。
为什么逃脱序列不起作用?
答案 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等模拟器中更改标题。