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

Javascriptnode.js

Javascript Problem Overview


The code snippet shown below works great for obtaining access to the stdout of a system command. Is there some way that I can modify this code so as to also get access to the exit code of the system command and any output that the system command sent to stderr?

#!/usr/bin/node
var child_process = require('child_process');
function systemSync(cmd) {
  return child_process.execSync(cmd).toString();
};
console.log(systemSync('pwd'));

Javascript Solutions


Solution 1 - Javascript

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 - Javascript

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 - Javascript

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3311045View Question on Stackoverflow
Solution 1 - Javascriptlance.dolanView Answer on Stackoverflow
Solution 2 - Javascriptbbuckley123View Answer on Stackoverflow
Solution 3 - JavascriptinfografnetView Answer on Stackoverflow