nodejs child_process.spawnSync or child_process.spawn wrapped in yieldable generator which returns output

divramod picture divramod · Sep 4, 2015 · Viewed 16.5k times · Source

since a while i am trying to reach something that doesn't work out for me so far.

With nodejs, i like to run a interactive sh-command and work with the sh-command output after the command has exited. i like to write a yieldable generator-function that wraps the running of the interactive shell command and returns the output of the shell command.

Approach 1: shelljs

  • shelljs
  • I had some success with shelljs, but at some point it wont run further.
  • Question 1: is it possible to get shelljs to the point where i can inherit stdio and make the shelljs function yieldable?

Approach 2: child_process.spawnSync

  • child_process.spawnSync
  • at last i discovered child_process.spawnSync and was happy that, at least i can run interactive sh-commands without problems with options: { stdio: 'inherit' }
  • but i haven't found out how to get back the output of child_process.spawnSync.
  • Question 2: How to wrap spawnSync into a generator function that returns the child_process's output?

Approach 3: co-child-process

  • i also tried co-child-process.
  • it seems to run, but not interactive with stdio. there is a issue regarding this, i dont really understand.
  • Question 3: could someone explain me/ post a example how co-child-process will work with stdio inherit.

Approach 4: promisify child_process.spawn() with bluebird

  • i opened an issue on bluebird if child_process.spawn() is promisifiable

So my question at all. Can someone post me an example of how to run a interactive shell command that can be wrapped in a yieldable generator function that returns the output of the shell command? i am open for new approaches.

I created a npm module which is available on github where you can fork it and contribute.

thx in advance.

Answer

Tad Guski picture Tad Guski · Jan 20, 2016

I found the following which works on v5.4.1 . In the docs NodeJS Child Process it mentions the option encoding which has a default of 'buffer'. If you set this option to 'utf8', then instead of a buffer you get a string back with the results. You can get a string back from spawnSync because it is synchronous and blocks execution until the command completes. Here's a working example of a script which does an 'ls -l /usr' command and gets the output as a string object:

#!/usr/bin/env node

var cp = require('child_process');

var ls = cp.spawnSync('ls', ['-l', '/usr'], { encoding : 'utf8' });
// uncomment the following if you want to see everything returned by the spawnSync command
// console.log('ls: ' , ls);
console.log('stdout here: \n' + ls.stdout);

When you run it you get the following:

stdout here:
total 68
drwxr-xr-x   2 root root 36864 Jan 20 11:47 bin
drwxr-xr-x   2 root root  4096 Apr 10  2014 games
drwxr-xr-x  34 root root  4096 Jan 20 11:47 include
drwxr-xr-x  60 root root  4096 Jan 20 11:47 lib
drwxr-xr-x  10 root root  4096 Jan  4 20:54 local
drwxr-xr-x   2 root root  4096 Jan  6 01:30 sbin
drwxr-xr-x 110 root root  4096 Jan 20 11:47 share
drwxr-xr-x   6 root root  4096 Jan  6 00:34 src

The docs tell you what you can get back on the object in addition to stdout . If you want to see all the properties on the return object, uncomment the console.log (Warning: there's a LOT of stuff :) ).