In NodeJS, I want to be able to capture the output of a spawned process in memory (without a file being written, and without using the inherited sysout).
The documentation says I can use a Stream
…
object: Share a readable or writable stream that refers to a tty, file, socket, or a pipe with the child process. The stream’s underlying file descriptor is duplicated in the child process to the fd that corresponds to the index in the stdio array. The stream must have an underlying descriptor (file streams do not start until the ‘open’ event has occurred).
… however when I pass my custom stream, I get the error:
The argument 'stdio' is invalid. Received CustomWritableStream
I suspect I need to have an underlying descriptor – but I have no idea what this means, or how to implement it.
How can I get my capture Stream working? (Is it even possible?)
Code snippet:
class CustomWritableStream extends Writable {
captureBuffer: string = '';
_write(chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void) {
const chunkStr = chunk.toString();
this.captureBuffer += chunkStr;
callback();
}
}
const stdout = new CustomWritableStream()
const stderr = new CustomWritableStream()
const child = child_process.spawn(cmd, { ...opts, stdio: ['ignore', stdout, stderr] })
Similar:
- Incorrect value for stdio stream: WriteStream – but their solution was to use a FileDescriptor. I’d like to capture output in memory (if possible).
0
You can also directly pipe stdout
and stderr
, I’m also wondering why it’s throws an error. This might be a workaround to overcome the issue.
class CustomWritableStream extends Writable {
captureBuffer = '';
_write(chunk, encoding, callback) {
const chunkStr = chunk.toString();
this.captureBuffer += chunkStr;
callback();
}
}
const stdout = new CustomWritableStream();
const stderr = new CustomWritableStream();
const child = child_process.spawn('ls');
child.stdout.pipe(stdout);
child.stderr.pipe(stderr);
1
The following worked for me:
const child = child_process.spawn(cmd)
const stdout = []
child.stdout.on('data', data => {
stdout.push(data)
})
const errout = []
child.stderr.on('data', data => {
errout.push(data)
})
child.on('close', exitCode => {
if (exitCode === 0) {
return stdout.join('')
} else {
throw Error(errout.join(''))
}
})