I want to be able to display a commands output while it is running in child process and then process the output in my program. Is this possible?
var result = spawnSync('neo', ['-help'], {
stdio: 'inherit',
encoding: 'utf-8'
});
var savedOutput = result.stdout;
console.log(String(savedOutput));
So here is what I ended up doing.
I wrapped a great utility cross-spawn into my own module.
exec.js
var spawn = require('cross-spawn');
var util = require('util');
const Sugar = require('sugar');
// parses the output if it is in JSON format
function parse(str){
var outStr = str, res;
try {
res = JSON.parse(outStr.trim());
} catch (error) {
res = outStr;
}
return res;
}
module.exports = {
spawn() {
var args = Array.prototype.slice.call(arguments);
return new Promise(function (resolve, reject) {
var stdout = '', stderr = '';
var cp = spawn.apply(null, args);
cp.stdout.on('data', function (chunk) {
var res = parse(chunk.toString());
if (!res.result && res.commandOutput) { // pretty log
console.log(util.inspect(Sugar.Object.filter(res, (val, key) => key !== 'commandOutput'),{colors: true, depth:null}));
console.log(res.commandOutput);
} else console.log(res);
stdout += chunk;
});
cp.stderr.on('data', function (chunk) {
console.error(chunk.toString());
stderr += chunk;
});
cp.on('error', (e)=>{
reject((stderr && new Error(stderr)) || e);
})
.on('close', function (code) {
let output = parse(stdout);
if (code === 0) {
resolve(output);
} else {
let err = (output && output.errorMsg && new Error(output.errorMsg)) || new Error(stderr);
console.error(err);
reject(err);
}
});
});
},
};
and then I just use it as any regular Promise shell exec:
const exec = require('./lib/exec');
...
function execAndLog (){
...
return exec.spawn(...execArgs, opts).then(processOutput);
}