Используйте spawnSync для потоковой передачи вывода дочернего процесса, но сохраните вывод в родительской переменной.

Я хочу иметь возможность отображать вывод команд, пока он выполняется в дочернем процессе, а затем обрабатывать вывод в моей программе. Это возможно?

var result = spawnSync('neo', ['-help'], {
    stdio: 'inherit',
    encoding: 'utf-8'
});
var savedOutput = result.stdout;

console.log(String(savedOutput));

person dewdad    schedule 08.11.2016    source источник


Ответы (1)


Итак, вот что я в итоге сделал.

Я включил в свой собственный модуль отличную утилиту cross-spawn.

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);
                    }
                });
        });
    },
};

а затем я просто использую его как любой обычный исполняемый файл оболочки Promise:

const exec = require('./lib/exec'); ... function execAndLog (){ ... return exec.spawn(...execArgs, opts).then(processOutput); }

person dewdad    schedule 11.04.2017