ANSI 转义序列不会打印到 Windows 上的标准输出 [英] ANSI escape sequences aren't printed to stdout on Windows

查看:29
本文介绍了ANSI 转义序列不会打印到 Windows 上的标准输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to write an ANSI escape sequence to stdout using node.js on Windows, but it does not appear to work.

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

Specifically, I use ConEmu which does support a subset ANSI codes. I've created a test file which should rename the current console tab:

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

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

However, nothing happens when I run it. If I run node test > out.txt, the correct bytes are written to the output file.

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

Why don't the escape sequences work?

推荐答案

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

When node's stdout is connected to a non-interactive sink (ie piped or redirected to a file), bytes written to process.stdout are written as-is. Thus, running node test > out.txt produces expected results.

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

However, when node is connected to an interactive terminal in Windows, it (via libuv) actually parses all ANSI escape codes so that it can transparently emulate a unix TTY terminal using Windows APIs. This is what makes things like colors and repositioning the cursor work in Windows, since the Windows console does not support ANSI escape sequences.

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

Unknown and unsupported sequences are silently ignored.

因此,在 JS 调用 process.stdout.write() 和内部调用 WriteConsoleW()(节点实际输出到终端).

As a consequence, any unrecognized commands are discarded between JS calling process.stdout.write() and the internal call to WriteConsoleW() (where node actually outputs to the terminal).

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

This can be worked around from user code by opening a raw filesystem stream on fd 1.

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

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

Writing ANSI escape sequences to rawStdout will be emitted properly to the terminal.

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

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

(Of course this does not give the Windows console any magical new abilities; it will simply print the sequence verbatim and look like garbage. You must actually be using a terminal emulator of some kind that supports ANSI escape codes.)

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

To better achieve my particular ends, I ended up writing a module—console-title—that changes the console's title by writing the ANSI escape sequence on unix and calls the appropriate native API under Windows. This allows me to change the title in Windows' default console window and in emulators like ConEmu.

这篇关于ANSI 转义序列不会打印到 Windows 上的标准输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆