Node.js spawning a child process interactively with separate stdout and stderr streams

I tried the answer by user568109 but this does not work, which makes sense since the pipe only copies the data between streams. Hence, it only gets to process.stdout when the buffer is flushed... The following appears to work:

var TEST_EXEC = './test';

var spawn = require('child_process').spawn;
var test = spawn(TEST_EXEC, [], { stdio: 'inherit' });

//the following is unfortunately not working 
//test.stdout.on('data', function (data) {
//  console.log('stdout: ' + data);
//});

Note that this effectively shares stdio's with the node process. Not sure if you can live with that.


I was just revisiting this since there is now a 'shell' option available for the spawn command in node since version 5.7.0. Unfortunately there doesn't seem to be an option to spawn an interactive shell (I also tried with shell: '/bin/sh -i' but no joy). However I just found this which suggests using 'stdbuf' allowing you to change the buffering options of the program that you want to run. Setting them to 0 on everything produces unbuffered output for all streams and they're still kept separate.

Here's the updated javascript:

var TEST_EXEC = './test';

var spawn = require('child_process').spawn;
var test = spawn('stdbuf', ['-i0', '-o0', '-e0', TEST_EXEC]);

test.stdout.on('data', function (data) {
  console.log('stdout: ' + data);
});

test.stderr.on('data', function (data) {
  console.log('stderr: ' + data);
});

// Simulate entering data for getchar() after 1 second
setTimeout(function() {
  test.stdin.write('\n');
}, 1000);

Looks like this isn't pre-installed on OSX and of course not available for Windows, may be similar alternatives though.


You can do this :

var TEST_EXEC = 'test';
var spawn = require('child_process').spawn;
var test = spawn(TEST_EXEC);

test.stdin.pipe(process.stdin);
test.stdout.pipe(process.stdout);
test.stderr.pipe(process.stderr);

When you use events on stdout and stderr to print the output on console.log, you will get jumbled output because of asynchronous execution of the functions. The output will be ordered for a stream independently, but output can still get interleaved among stdin,stdout and stderr.