5

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

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');

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?

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
josh3736
  • 139,160
  • 33
  • 216
  • 263

1 Answers1

7

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.

josh3736
  • 139,160
  • 33
  • 216
  • 263
  • Curious; I wonder how ConEmu makes standard output look like a console window? That's a problem that pops up now and then, e.g., http://stackoverflow.com/q/12534018/886887, and there's no known solution. Or perhaps node.js is using a non-standard method to decide whether stdout is interactive? I'll have to look into that ... – Harry Johnston Dec 20 '14 at 03:55
  • Because there is a real console window. ConEmu hides the real Windows console window and duplicates its output. Go to menu > Debug > Real console to see it. – josh3736 Dec 20 '14 at 21:11