Building CLI tool in nodejs, child process output is not seen

44 views Asked by At

I am Building a command line tool in node, and as part of this tool I need to execute commands that I have in my system. The problem is that I don't get the piped output from the child process that I spawn in the program

The code that executed the child process:

import * as Child_process from "child_process";

export function asyncExec(command: string): Promise<string> {
  return new Promise((resolve, reject) => {
    const child = Child_process.spawn(command, { shell: true });
    child.stdout?.pipe(process.stdout);
    child.on("error", (err) => {
      reject(err);
    });
    child.on("exit", (code) => {
      if (code === 0) {
        resolve(code.toString());
      } else {
        reject(new Error(`Process exited with code ${code}`));
      }
    });
  });
}


I have had another version of this code to try and make it work that uses exec


import * as Child_process from "child_process";

export function asyncExec(command: string): Promise<string> {
  return new Promise((resolve, reject) => {
    const child = Child_process.exec(command, (err, stdout, stderr) => {
      if (err) {
        reject(new Error(stderr || err.message));
      } else {
        resolve(stdout);
      }
    });
    child.stdout?.pipe(process.stdout);
  });
}

The stream of the stdout of the child process is not being printed, it is only printed after the promise has resolved

Why ? what can I do to fix this ?

2

There are 2 answers

0
Eitank On BEST ANSWER

The fix to the problem was doing the following: const child = Child_process.spawn(command, { shell: true, stdio: "inherit" });

1
Naor Tedgi On

it depends on the terminal command you are executing

process.stdout is a readable stream with an highWaterMark value of 16384 by default.

if the output is less then this size then you get all your response once the stream ends , else you will get it on every chunk of data

try for example a large output with a time out

await asyncExec("printf 'k%.0s' {1..100} ");

await asyncExec("printf 'k%.0s' {1..1000000000} ");

Further reading on streams highWaterMark there is a great explanation here:

https://stackoverflow.com/a/45905930/4267015