I want to spawn a child process and have *all* output go to the same file.
I tried this:
var fs = require('fs'), childProcess = require('child_process');
var output = fs.openSync('/tmp/output.log', 'w');
childProcess.spawn('bash', ['-c', 'echo STOUT; echo STDERR >&2; echo DONE;'], {stdio: ['ignore', output, output]});
Which presumably provides the same FD for both stdout and stderr in the child process. Looking at the file produced, I get:
stderr is apparently being ignored. Looking at the child_process docs, there's an example that opens *two* versions of the same file (in append mode), and uses this for stdout / stderr. Since I want to truncate the file (not append), I tried:
var fs = require('fs'), childProcess = require('child_process');
var output = fs.openSync('/tmp/output.log', 'w');
var output2 = fs.openSync('/tmp/output.log', 'a');
childProcess.spawn('bash', ['-c', 'echo STOUT; echo STDERR >&2; echo DONE;'], {stdio: ['ignore', output, output2]});
But it looks like the write stream is not playing nice and is overwriting the other stream's output, as I get:
So I guess I have to explicitly truncate the file first, then open two append streams to it?
fs.closeSync(fs.openSync('/tmp/output.log', 'w'));
var output = fs.openSync('/tmp/output.log', 'a');
var output2 = fs.openSync('/tmp/output.log', 'a');
childProcess.spawn('bash', ['-c', 'echo STOUT; echo STDERR >&2; echo DONE;'], {stdio: ['ignore', output, output2]});
Which finally gives me the desired output:
For kicks, I also tried reusing a single append stream:
fs.closeSync(fs.openSync('/tmp/output.log', 'w'));
var output = fs.openSync('/tmp/output.log', 'a');
childProcess.spawn('bash', ['-c', 'echo STOUT; echo STDERR >&2; echo DONE;'], {stdio: ['ignore', output, output]});
But that gave me the same results as my initial attempt (no stderr at all).
I guess I've discovered *how* to do this (my third attempt), but that seems pretty ugly. Can anyone suggest a better way? In python, we can explicitly redirect the child's stderr to stdout:
output = open('/tmp/output.log', 'w');
subprocess.Popen(['bash', '-c', 'echo STOUT; echo STDERR >&2; echo DONE;'], stderr = subprocess.STDOUT)
Is there anything similar in nodejs, or am I stuck with explicitly truncating the file, followed by opening two append-mode descriptors?
Cheers,
- Tim.