【问题标题】:Understanding child_process module and exec functionality when using it to execute a file使用 child_process 模块执行文件时了解 child_process 模块和 exec 功能
【发布时间】:2019-05-25 02:01:29
【问题描述】:

我是 node.js 的新手,并试图理解语法以及代码中逐行发生的确切情况。此代码运行带有一个参数 arg1 的文件 hello.js,并需要一些时间来执行。文件控制台每隔几秒钟就会注销它正在处理的当前命令。我想知道:

1) 如何停止文件运行(出现问题时中止);

2) 如何将当前命令,即文件被控制台注销,传回客户端;

3) 什么',孩子;'部分语法和 '.on(' 部分语法。非常感谢。

此代码在服务器端运行,由客户端的 jQuery POST 发起。客户端向服务器端发送一个参数,服务器将该参数作为参数传递到文件中并运行它。当文件运行时,它使用 console.log 每隔几秒输出一次信息。

我想将该信息实时传递回 jQuery 帖子,以便可以在客户端实时获取每个命令。我也不理解代码中的 '.on('data', )' 部分。 .on 是否意味着“完成”或“继续执行此操作”,而且我不理解“.exec,孩子;”语法的一部分。

var myExecute = require('child_process').exec, child;

var shellScript = myExecute('node hello.js arg1'); //run a file with an argument

shellScript.stdout.on('data', (data)=>{
      console.log(data);//file output console logs appearing here in real time                
});
shellScript.stderr.on('data', (data)=>{ 
      console.error(data);
});```

I am not getting any error messages. Currently the file is running and accepting the argument param passed in. I want to be able to abort this process from the client side once it had begun and I want to get back the data that the file is console logging and pass it back to the client side jQuery POST in real time.

【问题讨论】:

  • 能否在问题中添加myExecute的定义? node中有多种执行命令的方式,知道你在用哪一种会很有帮助

标签: node.js child-process


【解决方案1】:

1)如何停止文件运行(出现问题时中止);

要停止子进程,您可以使用函数 kill(),在您的情况下,它会是这样的:shellScript.kill();

2)如何将当前命令,即文件被控制台注销,传回客户端;

您在这方面没有提供太多上下文,但您应该使用stdout 的回调(阅读下面的示例)

3) 什么',孩子;'部分语法和 '.on(' 他们语法的一部分。

您示例中的child 只是一个变量,如果我不得不猜测,它存在只是因为代码已被复制粘贴。如果我不得不再次猜测,我会说child 旨在用作对子进程的引用,但您却选择了shellScript。请记住,在进行导入的同一位置声明变量不是一个好习惯,它会使人们感到困惑!

.on 部分是订阅事件的一种方式,在这种情况下,您订阅的是子进程的标准输出和标准错误。这意味着只要进程向 stdout/stderr 写入内容,就会调用该函数(这并不完全准确,数据被缓冲了)。

这里是您的代码的副本,其中包含一些 cmets,希望它现在更有意义。

// import child_process API
var myExecute = require('child_process').exec;

// I think this is a proper use of child
var child = myExecute('node hello.js arg1');

// do something anytime there's data to read
child.stdout.on('data', (data)=>{
    console.log('STDOUT from child process: ', data);

    // TODO: Send data back to client side
});

// do something when the process writes to stderr
// Note: console.log() writes to stdout, console.error() writes to stderr
child.stderr.on('data', (data)=>{ 
    console.error('error detected: ', data);
    // kill child process
    child.kill();

    // TODO: Send error data to client
});

作为个人说明,我宁愿只导入child_process,然后调用child_process.exec,以防我以后需要另一个函数。像这样:

var child_process = require('child_proces');

var child = child_process.exec(...)

【讨论】:

    【解决方案2】:

    您可以创建一个函数并传递回调,以便在有 data 事件时将其传递给回调。 stdout[虽然名称选择不佳]在这种情况下是回调。

    const executeCommand = (cmd, finish, stdout) => {
          console.log(`cmd : ${cmd}`);
    
          let proc = child.exec(cmd);
          proc.stdout.on('data', function(data) {
            if (stdout)
              stdout(data);
          });
          proc.stderr.on('data', function(data) {
            console.log(`stderr - ${data}`);
            proc.kill();
          });
          proc.on('close', function(code) {
             finish(code);
          });
        }
    

    你现在可以调用那个方法了。

    let command = 'ls -la'; // sample
    executeCommand(command, function(code) {
             // this one is invoked when *close* event is emitted from child process
            //code === 0 meaning it ran fine.
            if(code === 255) {
              // meaning SSH connection was not successful
              return reject(new Error('Error in establishing SSH connection'));
            }
            return resolve(`message`);
          }, function(data) {
              // you get back the data here
              // can check for certain value
          });
    

    我不完全确定您是否可以将数据发送到 JQuery post 方法,因为它将在单独的进程上运行,但您可以使用套接字广播到房间或将该数据发送到特定的套接字客户端。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-24
      • 1970-01-01
      • 2015-07-12
      • 2021-06-17
      • 2021-05-17
      • 1970-01-01
      • 2022-08-04
      • 1970-01-01
      相关资源
      最近更新 更多