【问题标题】:How to execute multiple shell commands using node.js?如何使用 node.js 执行多个 shell 命令?
【发布时间】:2015-01-20 09:47:34
【问题描述】:

也许我还没有深入了解异步范式,但我想做这样的事情:

var exec, start;
exec = require('child_process').exec;
start = function() {
  return exec("wc -l file1 | cut -f1 -d' '", function(error, f1_length) {
    return exec("wc -l file2 | cut -f1 -d' '", function(error, f2_length) {
      return exec("wc -l file3 | cut -f1 -d' '", function(error, f3_length) {
        return do_something_with(f1_length, f2_length, f3_length);
      });
    });
  });
};

每次我想添加一个新的 shell 命令时都嵌套这些回调似乎有点奇怪。难道没有更好的办法吗?

【问题讨论】:

标签: node.js


【解决方案1】:

正如哈维所说,您可以使用 TwoStep。另一方面,我使用Async JS 库。您的代码可能如下所示:

async.parallel([
    function(callback) {
        exec("wc -l file1 | cut -f1 -d' '", function(error, f1_length) {
            if (error)
                return callback(error);
            callback(null, f1_length);
        });
    },
    function(callback) {
        exec("wc -l file2 | cut -f1 -d' '", function(error, f2_length) {
            if (error)
                return callback(error);
            callback(null, f2_length);
        });
    },
    function(callback) {
        exec("wc -l file3 | cut -f1 -d' '", callback);
    }
],
function(error, results) {
    /* If there is no error, then
       results is an array [f1_length, f2_length, f3_length] */
    if (error)
        return console.log(error);
    do_something_with(results);
});

异步提供了许多其他选项。阅读文档并尝试一下!请注意,对于f3_length,我只是在调用exec 时使用了callback。您也可以使用其他调用来执行此操作(因此您的代码会更短)。我只是想向您展示它是如何工作的。

【讨论】:

    【解决方案2】:

    我个人在这些情况下使用TwoStep

    var TwoStep = require("two-step");
    var exec, start;
    exec = require('child_process').exec;
    start = function() {
      TwoStep(
        function() {
          exec("wc -l file1 | cut -f1 -d' '", this.val("f1_length"));
          exec("wc -l file2 | cut -f1 -d' '", this.val("f2_length"));
          exec("wc -l file3 | cut -f1 -d' '", this.val("f3_length"));
        },
        function(err, f1_length, f2_length, f3_length) {
          do_something_with(f1_length, f2_length, f3_length);
        }
      );
    };
    

    也就是说,那里有大量的流控制库。我鼓励你尝试一下:https://github.com/joyent/node/wiki/Modules#wiki-async-flow

    【讨论】: