2
const spawnSync = require('child_process').spawnSync;
let x = spawnSync('bash', ['-c', 'echo "1stdout" ; echo "2stderr" >&2 ; echo "3stdout"']);

(The bash command is only an example. The command could be ls or wget or git - doesn't matter.)

Of course, I can access stdout of the subprocess with x.stdout and stderr with x.stderr so I will get

1stdout
3stdout

and

2stderr

respectively. However, what I want is a single variable which contains

1stdout
2stderr
3stdout

I have a feeling that there is something in options.stdio which could help, but I wasn't able to figure it out.

finefoot
  • 9,914
  • 7
  • 59
  • 102
  • You could pipe both stdout and stderr to one stream, which you would in turn pipe to your variable, but I suspect that getting a bug free implementation will be extremely tricky since major companies like heroku often end up with slightly our of order logs when there's a lot of output – schu34 Jan 17 '18 at 23:35

1 Answers1

1

If you're OK with writing the interwoven output to a file:

let fd = createWriteStream('path', options)

// wait on fd 'open' event however you want to.

let results = child_process.spawnSync('ls', args, {stdio: [null, fd, fd]})

fs.closeSync(fd)

If you want it as a string then the simplest approach is to just read the file. I think the alternative is to create a duplex stream and pass the stream object in {stdio: [null, streamObj, streamObj]}. That would require handling the stream events and building the string on the fly and is probably not required if you're using spawnSync().

bmacnaughton
  • 4,950
  • 3
  • 27
  • 36