在 node.js 中执行并获取 shell 命令的输出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12941083/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 16:29:47  来源:igfitidea点击:

Execute and get the output of a shell command in node.js

node.jsshellcommand-line-interface

提问by Anderson Green

In a node.js, I'd like to find a way to obtain the output of a Unix terminal command. Is there any way to do this?

在 node.js 中,我想找到一种方法来获取 Unix 终端命令的输出。有没有办法做到这一点?

function getCommandOutput(commandString){
    // now how can I implement this function?
    // getCommandOutput("ls") should print the terminal output of the shell command "ls"
}

回答by Renato Gama

Thats the way I do it in a project I am working now.

这就是我在我现在工作的项目中做的方式。

var exec = require('child_process').exec;
function execute(command, callback){
    exec(command, function(error, stdout, stderr){ callback(stdout); });
};

Example: Retrieving git user

示例:检索 git 用户

module.exports.getGitUser = function(callback){
    execute("git config --global user.name", function(name){
        execute("git config --global user.email", function(email){
            callback({ name: name.replace("\n", ""), email: email.replace("\n", "") });
        });
    });
};

回答by hexist

You're looking for child_process

您正在寻找child_process

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

child = exec(command,
   function (error, stdout, stderr) {
      console.log('stdout: ' + stdout);
      console.log('stderr: ' + stderr);
      if (error !== null) {
          console.log('exec error: ' + error);
      }
   });


As pointed out by Renato, there are some synchronous exec packages out there now too, see sync-execthat might be more what yo're looking for. Keep in mind though, node.js is designed to be a single threaded high performance network server, so if that's what you're looking to use it for, stay away from sync-exec kinda stuff unless you're only using it during startup or something.

正如 Renato 所指出的,现在也有一些同步 exec 包,请参阅sync-exec这可能是您正在寻找的更多内容。不过请记住,node.js 被设计为单线程高性能网络服务器,所以如果这就是你想要使用它的目的,请远离 sync-exec 有点东西,除非你只在启动期间使用它或者其他的东西。

回答by Ansikt

If you're using node later than 7.6 and you don't like the callback style, you can also use node-util's promisifyfunction with async / awaitto get shell commands which read cleanly. Here's an example of the accepted answer, using this technique:

如果您使用的是 7.6 以后的 node 并且您不喜欢回调样式,您还可以使用 node-util 的promisify函数 withasync / await来获取读取干净的 shell 命令。这是使用此技术的已接受答案的示例:

const { promisify } = require('util');
const exec = promisify(require('child_process').exec)

module.exports.getGitUser = async function getGitUser () {
  const name = await exec('git config --global user.name')
  const email = await exec('git config --global user.email')
  return { name, email }
};

This also has the added benefit of returning a rejected promise on failed commands, which can be handled with try / catchinside the async code.

这还有一个额外的好处,即在失败的命令上返回一个被拒绝的承诺,可以try / catch在异步代码内部处理。

回答by Damjan Pavlica

Thanks to Renato answer, I have created a really basic example:

感谢 Renato 的回答,我创建了一个非常基本的示例:

const exec = require('child_process').exec

exec('git config --global user.name', (err, stdout, stderr) => console.log(stdout))

It will just print your global git username :)

它只会打印您的全局 git 用户名 :)

回答by Amin NAIRI

Requirements

要求

This will require Node.js 7 or later with a support for Promises and Async/Await.

这将需要支持 Promises 和 Async/Await 的 Node.js 7 或更高版本。

Solution

解决方案

Create a wrapper function that leverage promises to control the behavior of the child_process.execcommand.

创建一个包装函数,利用 promise 来控制child_process.exec命令的行为。

Explanation

解释

Using promises and an asynchronous function, you can mimic the behavior of a shell returning the output, without falling into a callback hell and with a pretty neat API. Using the awaitkeyword, you can create a script that reads easily, while still be able to get the work of child_process.execdone.

使用 Promise 和异步函数,您可以模拟 shell 返回输出的行为,而不会陷入回调地狱,并且具有非常简洁的 API。使用await关键字,您可以创建一个易于阅读的脚本,同时仍然能够child_process.exec完成工作。

Code sample

代码示例

const childProcess = require("child_process");

/**
 * @param {string} command A shell command to execute
 * @return {Promise<string>} A promise that resolve to the output of the shell command, or an error
 * @example const output = await execute("ls -alh");
 */
function execute(command) {
  /**
   * @param {Function} resolve A function that resolves the promise
   * @param {Function} reject A function that fails the promise
   * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
   */
  return new Promise(function(resolve, reject) {
    /**
     * @param {Error} error An error triggered during the execution of the childProcess.exec command
     * @param {string|Buffer} standardOutput The result of the shell command execution
     * @param {string|Buffer} standardError The error resulting of the shell command execution
     * @see https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
     */
    childProcess.exec(command, function(error, standardOutput, standardError) {
      if (error) {
        reject();

        return;
      }

      if (standardError) {
        reject(standardError);

        return;
      }

      resolve(standardOutput);
    });
  });
}

Usage

用法

async function main() {
  try {
    const passwdContent = await execute("cat /etc/passwd");

    console.log(passwdContent);
  } catch (error) {
    console.error(error.toString());
  }

  try {
    const shadowContent = await execute("cat /etc/shadow");

    console.log(shadowContent);
  } catch (error) {
    console.error(error.toString());
  }
}

main();

Sample Output

样本输出

root:x:0:0::/root:/bin/bash
[output trimmed, bottom line it succeeded]

Error: Command failed: cat /etc/shadow
cat: /etc/shadow: Permission denied

Try it online.

在线试一下。

Repl.it.

复制

External resources

外部资源

Promises.

承诺

child_process.exec.

child_process.exec.

Node.js support table.

Node.js 支持 table