通过spawn

时间:2016-11-19 00:42:00

标签: python json node.js spawn

我有一个带有两个参数的python脚本;目录和文件名。

python脚本将从提供的目录中的特定文件创建一个JSON对象,并使用名称作为第二个参数保存它。

但是,如果第二个参数等于string" stream",则JSON数据将输出到STDOUT。

我写了一个节点脚本,它生成一个子进程来从终端调用python脚本,它按预期工作。



"use strict";

const spawn = require("child_process").spawn;

const command = "(path to python)";
const loc = "(path to .py script)";

const acct = process.argv[2];
const output = process.argv[3];

let callPy = spawn(command, ["erik.py", acct, output], {
    cwd: loc,
    stdio: "pipe"
});

callPy.stdout.on("data", (data) => {
    if (data.toString() === "success") {
        console.log(acct, "generated");
    } else {
        console.log(data.toString());
    }
});




编辑:

我已将此问题取消标记为已解决:在花费更多时间尝试实现此问题之后,我还没有找到一个令人满意的解决方案,它允许我从节点同步调用子进程,发出python脚本信号以发出JSON数据,接收数据,然后将数据发送到浏览器。我尝试在子进程上使用promise链:



let child = require("child_process").spawn; // or spawnSync

let spawn = () => {
    let spawned = child(command, args, options,(err, stdout, stderr) => {
        if (err) { console.log(err) };
    });
    return spawned
};

let listen = (child) => {
    child.stdout.on("data", (data) => {
        console.log("PID", child.pid);
        console.log("data from listen func: ", data);
        return child
    });
};

let kill = (child) => {
    child.kill( "SIGTERM" );
}

var p = new Promise((res, e) => {
    res( spawn() )
    e( console.error(e) )
});

p.then(result => {
    return listen(result);
    })
    p.then(result => {
        return kill(result);
});
    




使用spawn()子项在返回任何数据之前终止 使用spawnSync()承诺链尝试(并且失败)在孩子产生之前监听孩子的身份

我还没有尝试使用websockets来传输数据,但我怀疑这会解决这个问题,承诺是在promise链从python脚本中检索块之前将一个空对象返回到我的路由器函数调用。

欢迎任何进一步的见解。

2 个答案:

答案 0 :(得分:1)

所以你至少需要做两件事

  • 使用spawn
  • 对要执行的命令进行排队的方法
  • 等待执行命令并在每个可执行文件终止时加入进程的异步模式

简约的例子是

var cmd = new CommandLine({ 
    debug : true, 
    error : true, 
    delay : true });
// commandItemsArray is a list of commands list, command options, command arguments
commandItemsArray = [ ['ls','-l','./'], ['ls','-a','./'] ];
cmd.executeCommands( commandItemsArray
, function(results) {
    console.log( results );
}
, function(error) {
    console.log( error );
});

npm上有几个包可以同时执行(搜索节点cli,命令行等),其中一个node-commander使用Promise.all模式来完成第二个任务:

      function PromiseAll(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) {
                return 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

答案 1 :(得分:0)

我能够相对简单地使用websockets来解决这个问题:

客户端提交请求,该请求通过socket.IO传递给服务器,接收到请求并触发spawn事件,当块完成后,发出一个终止事件,触发杀死子进程和将数据返回给客户端