【问题标题】:node.js - Accessing the exit code and stderr of a system commandnode.js - 访问系统命令的退出代码和标准错误
【发布时间】:2015-09-30 19:40:54
【问题描述】:

下面显示的代码 sn-p 非常适合获取对系统命令的标准输出的访问。有什么方法可以修改此代码,以便还可以访问系统命令的退出代码以及系统命令发送到 stderr 的任何输出?

#!/usr/bin/node
var child_process = require('child_process');
function systemSync(cmd) {
  return child_process.execSync(cmd).toString();
};
console.log(systemSync('pwd'));

【问题讨论】:

    标签: javascript node.js


    【解决方案1】:

    您不需要异步操作。你可以保留你的 execSync 函数。

    将其包装在 try 中,传递给 catch(e) 块的错误将包含您要查找的所有信息。

    var child_process = require('child_process');
    
    function systemSync(cmd) {
      try {
        return child_process.execSync(cmd).toString();
      } 
      catch (error) {
        error.status;  // Might be 127 in your example.
        error.message; // Holds the message you typically want.
        error.stderr;  // Holds the stderr output. Use `.toString()`.
        error.stdout;  // Holds the stdout output. Use `.toString()`.
      }
    };
    
    console.log(systemSync('pwd'));
    

    如果没有抛出错误,那么:

    • 状态保证为0
    • stdout 是函数返回的内容
    • stderr 几乎肯定是空的,因为它成功了。

    在极少数情况下,命令行可执行文件返回一个 stderr 并以状态 0(成功)退出,并且您想读取它,您将需要 async 函数。

    【讨论】:

    • 感谢 lance - 创建了这个 npm 模块 - shelljs.exec - 它将您在这里放置的所有逻辑包装成一个漂亮的小数据包 - 干杯:D
    • 我会说进程返回 0 的退出代码实际上很常见,但在 stderr 中也包含输出。 stderr 经常用于调试信息和其他与命令输出不直接相关的信息。
    • @IshaanGandhi 如果这是真的,我想确认行为更改的版本。我还想知道是否可以传递一些配置来启用这种预期的行为。为了自己确认这一点,我个人不再从事任何节点项目了
    • 我的错误。我认为它应该一般工作。当我使用节点 8 在电子中运行命令时,没有抛出错误,但从节点 repl 中抛出了一个错误。可能电子中有一个错误。
    • 需要注意的是,如果父进程在超过 maxBuffer 时杀死子进程,execSync 会抛出错误,但是error.status will be null !
    【解决方案2】:

    您将需要 exec 的异步/回调版本。返回 3 个值。最后两个是标准输出和标准错误。此外,child_process 是一个事件发射器。监听exit 事件。回调的第一个元素是退出代码。 (从语法上很明显,您需要使用节点 4.1.1 来让下面的代码按所写的那样工作)

    const child_process = require("child_process")
    function systemSync(cmd){
      child_process.exec(cmd, (err, stdout, stderr) => {
        console.log('stdout is:' + stdout)
        console.log('stderr is:' + stderr)
        console.log('error is:' + err)
      }).on('exit', code => console.log('final exit code is', code))
    }
    

    尝试以下方法:

    `systemSync('pwd')`
    
    `systemSync('notacommand')`
    

    你会得到:

    final exit code is 0
    stdout is:/
    stderr is:
    

    接着是:

    final exit code is 127
    stdout is:
    stderr is:/bin/sh: 1: notacommand: not found
    

    【讨论】:

    • > 你会想要 exec 的异步/回调版本。
    • 我实际上是在尝试同步进行。我了解到,我显然正在用这种方法抓住稻草。异步方法效果很好。感谢您的意见。
    • @user3311045 - 如果您接受我的回答,那就太好了。但是,如果您想等待可以通过同步选项弄清楚如何做到这一点的人,那很酷。我试图通过execSync 解决这个问题,但我认为没有办法。
    【解决方案3】:

    您也可以使用child_process.spawnSync(),因为它会返回更多:

    return: 
    pid <Number> Pid of the child process
    output <Array> Array of results from stdio output
    stdout <Buffer> | <String> The contents of output[1]
    stderr <Buffer> | <String> The contents of output[2]
    status <Number> The exit code of the child process
    signal <String> The signal used to kill the child process
    error <Error> The error object if the child process failed or timed out
    

    所以您要查找的退出代码是ret.status.

    【讨论】:

      猜你喜欢
      • 2019-01-26
      • 2022-06-28
      • 2013-09-14
      • 2015-04-29
      • 1970-01-01
      • 2019-08-02
      • 2012-03-24
      • 2016-09-10
      • 1970-01-01
      相关资源
      最近更新 更多