Pass child process output to terminal window, but also capture in a variable

Viewed 167

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.

0 Answers
Related