I know that I can pass a child process's stdout and stderr through to the terminal by passing the option { stdio: 'inherit' }, i.e.
child_process.spawnSync('echo', ['hello'], { stdio: 'inherit' })
And I know that I can instead capture it in a variable by omitting that option:
const child = child_process.spawnSync('echo', ['hello'], { stdio: 'inherit' })
const output = child.stdout.toString()
But what if I want to both let the output flow through to the terminal and capture the output in a variable? My current solution looks like this:
const child = spawn('echo', ['hello'])
child.stdout.pipe(process.stdout)
child.stderr.pipe(process.stderr)
let stdout = ''
let stderr = ''
child.stdout.on('data', buffer => {
stdout += buffer.toString()
})
child.stderr.on('data', buffer => {
stderr += buffer.toString()
})
child.stdout.on('close', buffer => {
console.log('captured stdout', stdout)
})
child.stderr.on('close', buffer => {
console.log('captured stderr', stderr)
})
But the pipe approach doesn't work as perfectly as { stdio: inherit }. If the command being run updates an existing line of stdout (imagine a progress % that is incrementing), I don't see that update happening in real time. I only see the end result.