node.js - Accessing the exit code and stderr of a system command

Solution 1:

You do not need to do it Async. You can keep your execSync function.

Wrap it in a try, and the Error passed to the catch(e) block will contain all the information you're looking for.

var child_process = require('child_process');

function systemSync(cmd) {
  try {
    return child_process.execSync(cmd).toString();
  } 
  catch (error) {
    error.status;  // Might be 127 in your example.
    error.message; // Holds the message you typically want.
    error.stderr;  // Holds the stderr output. Use `.toString()`.
    error.stdout;  // Holds the stdout output. Use `.toString()`.
  }
};

console.log(systemSync('pwd'));

If an error is NOT thrown, then:

  • status is guaranteed to be 0
  • stdout is what's returned by the function
  • stderr is almost definitely empty because it was successful.

In the rare event the command line executable returns a stderr and yet exits with status 0 (success), and you want to read it, you will need the async function.

Solution 2:

You will want the async/callback version of exec. There are 3 values returned. The last two are stdout and stderr. Also, child_process is an event emitter. Listen for the exit event. The first element of the callback is the exit code. (Obvious from the syntax, you'll want to use node 4.1.1 to get the code below to work as written)

const child_process = require("child_process")
function systemSync(cmd){
  child_process.exec(cmd, (err, stdout, stderr) => {
    console.log('stdout is:' + stdout)
    console.log('stderr is:' + stderr)
    console.log('error is:' + err)
  }).on('exit', code => console.log('final exit code is', code))
}

Try the following:

`systemSync('pwd')`

`systemSync('notacommand')`

And you will get:

final exit code is 0
stdout is:/
stderr is:

Followed by:

final exit code is 127
stdout is:
stderr is:/bin/sh: 1: notacommand: not found

Solution 3:

You may also use child_process.spawnSync(), as it returns much more:

return: 
pid <Number> Pid of the child process
output <Array> Array of results from stdio output
stdout <Buffer> | <String> The contents of output[1]
stderr <Buffer> | <String> The contents of output[2]
status <Number> The exit code of the child process
signal <String> The signal used to kill the child process
error <Error> The error object if the child process failed or timed out

So the exit code you're looking for would be ret.status.