Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 节点生成多个shell进程问题_Node.js_Shell_Process_Promise_Spawn - Fatal编程技术网

Node.js 节点生成多个shell进程问题

Node.js 节点生成多个shell进程问题,node.js,shell,process,promise,spawn,Node.js,Shell,Process,Promise,Spawn,我开发了一个模块,使用child\u进程spawn执行通用命令。 我在这个模块中有两个api,一个是单命令执行api,CommandLine.execute,另一个是多命令执行api,CommandLine.executeCommands,我以这种方式调用它们: // commandItemsArray is a list of commands list // that is an array of [command, options, arguments] commandItemsArr

我开发了一个模块,使用
child\u进程
spawn
执行通用命令。 我在这个模块中有两个api,一个是单命令执行api,
CommandLine.execute
,另一个是多命令执行api,
CommandLine.executeCommands
,我以这种方式调用它们:

// commandItemsArray is a list of commands list
// that is an array of [command, options, arguments]
  commandItemsArray = [ ['ls','-l','./'], ['ls','-a','./'] ];
  command.executeCommands( commandItemsArray
    , function(results) {
      console.log( results );
    }
    , function(error) {
      console.log( error );
    });

此模块是独立的(仅依赖于节点内置模块),代码如下:

(function() {

  var CommandLine;
  CommandLine = (function() {

    var cp = require('child_process');

    /**
     * Command line helper module
     * This module is standalone
     * @author: loretoparisi at gmail dot com
     */
    function CommandLine(options,logger) {
      var self=this;

      // defaults
      this._options = {
        // true to debug
        debug : false,
        // true to show errors
        error : true
      };

      // override defaults
      for (var attrname in options) { this._options[attrname] = options[attrname]; }

      /**
       * Wrappar around Promise.all
       */
      this.PromiseAll = function(items, block, done, fail) {
          var self = this;
          var promises = [],
              index = 0;
          items.forEach(function(item) {
              promises.push(function(item, i) {
                  return new Promise(function(resolve, reject) {
                      if (block) {
                          block.apply(this, [item, index, resolve, reject]);
                      }
                  });
              }(item, ++index))
          });
          Promise.all(promises).then(function AcceptHandler(results) {
              if (done) done(results);
          }, function ErrorHandler(error) {
              if (fail) fail(error);
          });
      }; //PromiseAll

    }

    /**
     * Execute a command
     * @param commands Array of command, options, arguments
     * @example ['ls','-l','./']
     * @param resolve Block success block
     * @param reject Block rejection block
     */
    CommandLine.prototype.execute = function(command, resolve, reject) {
      var self=this;
      resolve = resolve || function(results) {};
      reject = reject || function(error) {};
      return self.ExecutionBlock(item, index, resolve, reject);
    } //execute

    /**
     * Execute a list of commands
     * @param commands Array of command array of of command, options, arguments
     * @example [ ['ls','-l','./'], ['ls', '-a', './'] ]
     * @param resolve Block success block
     * @param reject Block rejection block
     */
    CommandLine.prototype.executeCommands = function(commands, resolve, reject) {
      var self=this;
      resolve = resolve || function(results) {};
      reject = reject || function(error) {};

      /**
       * Execution block handler
       */
      var ExecutionBlock = function(item, index, resolve, reject) {

        var executable = item[0]; // first elem is command
        var options = item.splice(1,item.length);

        if(self._options.debug) {
          console.log( item );
          console.log( executable, options.join(' ') );
        }

        var data = new Buffer("",'utf-8');
        // LP: now spawn the power!
        var child = cp.spawn(executable, options);
        // Listen for an exit event:
        child.on('exit', function(exitCode) {
          return resolve( { data : data.toString('utf-8'), code : exitCode } );
        });
        // Listen for stdout data
        child.stdout.on('data', function(_data) {
            console.log( ( new Buffer(_data)).toString() );
            data = Buffer.concat([data, _data]);
        });
        // child error
        child.stderr.on('data',
            function(data) {
              if(self._options.error) {
                console.log('err data: ' + data);
              }
              // on error, kill this child
              child.kill();
              return reject(new Error(data.toString()));
            }
        );

      } //ExecutionBlock

      self.PromiseAll(commands
        , function(item, index, _resolve, _reject) {
          ExecutionBlock(item, index, _resolve, _reject);
        }
        , function(results) { // aggregated results
          // all execution done here. The process exitCodes will be returned
            // array index is the index of the processed that exited
            return resolve(results);
          }
        , function(error) { // error
            return reject(error);
        });

    } //executeCommands

    return CommandLine;

  })();

  module.exports = CommandLine;

}).call(this);
我正在使用
承诺。all
生成多个进程,等待执行,并在节点
缓冲区中收集
stdout
输出,如:

    // Listen for stdout data
    child.stdout.on('data', function(_data) {
        console.log( ( new Buffer(_data)).toString() );
        data = Buffer.concat([data, _data]);
    });
在退出子事件中,我返回子进程退出代码和结构中的数据:

    child.on('exit', function(exitCode) {
      return resolve( { data : data.toString('utf-8'), code : exitCode } );
    });
虽然执行某些命令没有问题,但执行诸如
ls
之类的shell命令会返回意外的结果,例如我没有在
PromiseAll
方法的回调中获得预期的结果,我不理解为什么

self.PromiseAll(commands
        , function(item, index, _resolve, _reject) {
          ExecutionBlock(item, index, _resolve, _reject);
        }
        , function(results) { // aggregated results
          // all execution done here. The process exitCodes will be returned
            // array index is the index of the processed that exited
            return resolve(results);
          }
        , function(error) { // error
            return reject(error);
        }); 
一个疑问是关于节点
缓冲区
级联的解释,这似乎很棘手:

    var data = new Buffer("",'utf-8');
    // LP: now spawn the power!
    var child = cp.spawn(executable, options);
    // Listen for an exit event:
    child.on('exit', function(exitCode) {
      return resolve( { data : data.toString('utf-8'), code : exitCode } );
    });
    // Listen for stdout data
    child.stdout.on('data', function(_data) {
        console.log( ( new Buffer(_data)).toString() );
        data = Buffer.concat([data, _data]);
    });
我希望
{data:data.toString('utf-8')}
将整个缓冲区链接为字符串,但我想知道
utf-8
是否是
stdout
输出的正确编码,当然,假设我们正在讨论shell命令

    var data = new Buffer("",'utf-8');
    // LP: now spawn the power!
    var child = cp.spawn(executable, options);
    // Listen for an exit event:
    child.on('exit', function(exitCode) {
      return resolve( { data : data.toString('utf-8'), code : exitCode } );
    });
    // Listen for stdout data
    child.stdout.on('data', function(_data) {
        console.log( ( new Buffer(_data)).toString() );
        data = Buffer.concat([data, _data]);
    });