在 Node.js 中执行 bash 命令并获取退出代码

Execute bash command in Node.js and get exit code

我可以 运行 在 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)?我试过 运行ning

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

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

这 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
});

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

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

来自文档:

If a callback function is provided, it is called with the arguments (error, stdout, stderr). On success, error will be null. On error, error will be an instance of Error. The error.code property will be the exit code of the child process while error.signal will be set to the signal that terminated the process. Any exit code other than 0 is considered to be an error.

所以:

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

应该可以。

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 中测试。

如果有人正在寻找 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.