7

Synchronous child process calls are now available in the versions of Node.js that are under development (i.e. unstable). This is great news for writing shell scripts, as it will allow code like this:

var history = child_process.execSync('git log', { encoding: 'utf8' });
process.stdout.write(history);

However, for code aimed at the current stable version of Node.js (v0.10.30), synchronous child process calls are not available except via external libraries. The two most popular such libraries appear to be shelljs and exec-sync.

For shell scripts intended for use with v0.10.x, and which must call binaries or other executables and process their output, what are the relative pros and cons of these two libraries or other comparable libraries? Please provide code samples for illustration, if appropriate.

  • While it's a well-written question, this will probably be closed as too opinion-based :-/ – Bergi Aug 15 '14 at 02:15
  • Thanks. I hope it won't be closed, as it seems perfectly appropriate: essentially a refinement of [this question](http://stackoverflow.com/q/14458508/82216) . However, do say if you think I should flag it for migration to softwarerecs.stackexchange.com or similar –  Aug 15 '14 at 10:48
  • Hm, I don't know whether it's [on-topic there](http://softwarerecs.stackexchange.com/help/on-topic) either. – Bergi Aug 15 '14 at 11:16
  • 3
    Well, I'm not asking for opinions, I'm asking for concrete advantages/disadvantages to two precisely specified alternative programming strategies (in this case, using one library vs using another, for the same task). This sort of question has been asked and answered on SO for years. In any case, there's room for [inclusionism](https://en.wikipedia.org/wiki/Wikipedia:WikiProject_Inclusion) on SO/SE :) –  Aug 15 '14 at 11:28

1 Answers1

12

Let's look at three options: the two mentioned in the question, plus execsync.

shelljs

shelljs is much more than a library for calling child processes. Primarily, it is a cross-platform JavaScript implementation of several POSIX utilities and shell builtins: >, cat, cd, chmod, cp, dirs, echo, env, exec, exit, find, grep, ln, ls, mkdir, mv, popd, pushd, pwd, rm, sed, test, which. It also provides a couple of useful functions of its own: error() and tempdir().

Its exec function can be used to run an external executable synchronously.

Syntax example

Using global namespace:

require('shelljs/global');
var version = exec('node --version', {silent:true}).output;
console.log('version ' + version);

Alternatively, using local namespace:

var sh = require('shelljs');
var version = sh.exec('node --version', {silent:true}).output;
console.log('version ' + version);

Key stats/specs

  • Dependencies: 0
  • Dependents: 411
  • Downloads this month: 957851
  • License: BSD*

Pros

  • No dependencies.
  • Can be used via global or local namespace at developer's discretion.
  • Huge number of dependent packages and users, so likely to remain in use for some time.

Cons

  • Cannot distinguish a called executable's output to stderr from its output to stdout. Bug?
  • The shelljs documentation warns, "For long-lived processes, it's best to run exec() asynchronously as the current synchronous implementation uses a lot of CPU. This should be getting fixed soon."

exec-sync / execSync

exec-sync has been retired in favour of execSync. The rest of this section therefore refers to the latter.

The execSync library consists of a JavaScript wrapper around a C++ core. During the installation of execSync, the C++ core is compiled into a platform-appropriate NodeJS binary module.

Syntax example

var sh = require('execSync');
var version = sh.exec('node --version').stdout;
console.log('version ' + version);

Key stats/specs

  • Dependencies: 1
  • Dependents: 91
  • Downloads this month: 20525
  • License: MIT

Pros

  • Straightforward once installed.
  • Large number of dependent packages and users, so likely to remain in use for some time.

Cons

  • Not dependency-free.
  • Installation requires the presence of a C++ compiler.
  • Cannot distinguish a called executable's output to stderr from its output to stdout. Bug?

execsync

Worth mentioning here as it is easily confused with execSync (see above) by any case-insensitive search engine, other algorithm, or human. Confusing matters further, the author of execsync has used the orthography "execSync" at a few points in execsync's code and documentation.

Like execSync above, the execsync library consists of a JavaScript wrapper around a C++ core. During the installation of execsync, the C++ core is compiled into a platform-appropriate NodeJS binary module.

Syntax example

var sh = require('execsync');
var version = sh('node --version');
console.log('version ' + version);

Key stats/specs

  • Dependencies: 0
  • Dependents: 3
  • Downloads this month: 20233
  • License: NYSL

Pros

  • No dependencies.

Cons

  • Inconsistent internal orthography.
  • Installation requires the presence of a C++ compiler.
  • Documentation is in Japanese (not a "con" for everyone, admittedly).
  • Cannot distinguish a called executable's output to stderr from its output to stdout.
  • Small number of dependents, so presumably less entrenched in Node.js community.