【问题标题】:Execute bash command in Node.js and get exit code在 Node.js 中执行 bash 命令并获取退出代码
【发布时间】:2016-10-10 11:34:56
【问题描述】:

我可以像这样在 node.js 中运行 bash 命令:

var sys = require('sys')
var exec = require('child_process').exec;

function puts(error, stdout, stderr) { sys.puts(stdout) }
exec("ls -la", function(err, stdout, stderr) {
  console.log(stdout);
});

如何获取该命令的退出代码(本例中为ls -la)?我试过跑步

exec("ls -la", function(err, stdout, stderr) {
  exec("echo $?", function(err, stdout, stderr) {
    console.log(stdout);
  });
});

不管前一个命令的退出代码如何,这总是返回 0。我错过了什么?

【问题讨论】:

  • 您的第一个示例已经在 console.log 中为您提供了标准输出

标签: node.js bash exit-code


【解决方案1】:

这 2 个命令在不同的 shell 中运行。

要获取代码,您应该可以在回调中检查err.code

如果这不起作用,您需要添加一个exit 事件处理程序

例如

dir = exec("ls -la", function(err, stdout, stderr) {
  if (err) {
    // should have err.code here?  
  }
  console.log(stdout);
});

dir.on('exit', function (code) {
  // exit code is code
});

【讨论】:

  • 太棒了! exit 事件处理程序效果很好; err.code 仅在错误码不为 0 时返回数字。
  • 还有execSync(command[, options]) 给那些对同步版本感兴趣的人。 nodejs.org/api/…
【解决方案2】:

来自文档:

如果提供了callback 函数,则使用参数(error, stdout, stderr) 调用它。成功后,error 将变为 null。出错时,error 将是 Error 的一个实例。 error.code 属性将是子进程的退出代码,而error.signal 将设置为终止进程的信号。任何非 0 的退出代码都被视为错误。

所以:

exec('...', function(error, stdout, stderr) {
  if (error) {
    console.log(error.code);
  }
});

应该可以。

【讨论】:

    【解决方案3】:

    child_process.spawnSync()

    这个函数暴露了最好的同步接口:https://nodejs.org/api/child_process.html#child_process_child_process_spawnsync_command_args_options

    例子:

    #!/usr/bin/env node
    
    const child_process = require('child_process');
    let out;
    
    out = child_process.spawnSync('true');
    console.log('status: ' + out.status);
    console.log('stdout: ' + out.stdout.toString('utf8'));
    console.log('stderr: ' + out.stderr.toString('utf8'));
    console.log();
    
    out = child_process.spawnSync('false');
    console.log('status: ' + out.status);
    console.log('stdout: ' + out.stdout.toString('utf8'));
    console.log('stderr: ' + out.stderr.toString('utf8'));
    console.log();
    
    out = child_process.spawnSync('echo', ['abc']);
    console.log('status: ' + out.status);
    console.log('stdout: ' + out.stdout.toString('utf8'));
    console.log('stderr: ' + out.stderr.toString('utf8'));
    console.log();
    

    输出:

    status: 0
    stdout: 
    stderr: 
    
    status: 1
    stdout: 
    stderr: 
    
    status: 0
    stdout: abc
    
    stderr: 
    
    

    在 Node.js v10.15.1、Ubuntu 19.10 中测试。

    【讨论】:

      【解决方案4】:

      在节点文档中,我找到了回调函数的以下信息:

      成功时,error 将为空。出错时,error 将是 Error 的一个实例。 error.code 属性将是子进程的退出代码,而 error.signal 将设置为终止进程的信号。 0 以外的任何退出代码都被视为错误。

      【讨论】:

        【解决方案5】:

        如果有人在寻找await/Promise 版本:

        const exec = require('util').promisify(require('child_process').exec);
        
        let out = await exec(`echo hello`).catch(e => e);
        
        console.log(out.stdout); // outputs "hello"
        console.log(out.code); // Note: `out.code` is *undefined* if successful (instead of 0).
        

        如果命令成功,那么它将输出像{stderr, stdout} 这样的对象。如果它有一个非零退出代码,那么它将输出一个带有{stderr, stdout, code, killed, signal, cmd} 的错误对象和通常的JavaScript Error 对象属性,如messagestack

        【讨论】:

          猜你喜欢
          • 2012-01-02
          • 1970-01-01
          • 2013-01-01
          • 1970-01-01
          • 2012-10-08
          • 2014-06-14
          • 2018-11-04
          • 2018-03-29
          • 2011-09-22
          相关资源
          最近更新 更多