【问题标题】:ANSI escape sequences aren't printed to stdout on WindowsANSI 转义序列不会打印到 Windows 上的标准输出
【发布时间】:2015-02-18 23:20:46
【问题描述】:

我正在尝试在 Windows 上使用 node.js 将 ANSI 转义序列写入标准输出,但它似乎不起作用。

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

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

但是,当我运行它时,什么也没有发生。如果我运行node test > out.txt,则会将正确的字节写入输出文件。

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

【问题讨论】:

    标签: windows node.js terminal


    【解决方案1】:

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

    但是,当 node 连接到 Windows 中的交互式终端时,它(通过 libuv)实际上是parses all ANSI escape codes,因此它可以使用 Windows API 透明地模拟 unix TTY 终端。这就是使颜色和重新定位光标等操作在 Windows 中起作用的原因,因为 Windows 控制台不支持 ANSI 转义序列。

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

    因此,在 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 等模拟器中更改标题。

    【讨论】:

    • 好奇;我想知道 ConEmu 如何使标准输出看起来像控制台窗口?这是一个不时出现的问题,例如stackoverflow.com/q/12534018/886887,并且没有已知的解决方案。或者也许 node.js 正在使用非标准方法来决定 stdout 是否是交互式的?我得调查一下……
    • 因为有一个真正的控制台窗口。 ConEmu 隐藏真正的 Windows 控制台窗口并复制其输出。转到菜单 > 调试 > 真实控制台查看它。
    猜你喜欢
    • 2016-07-14
    • 2013-05-01
    • 1970-01-01
    • 2014-05-11
    • 2014-07-22
    • 2018-12-25
    • 2018-08-10
    • 1970-01-01
    相关资源
    最近更新 更多