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.
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.
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).
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 });
Writing ANSI escape sequences to rawStdout
will be emitted properly to the terminal.
rawStdout.write('\x1b]9;3;"abc"\x1b\x5c');
(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.)
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.