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

在 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"
}
182932 次浏览

你在找 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);
}
});

正如 Renato 指出的那样,现在也有一些同步执行包,看看 Sync-exec,它可能更符合你的要求。但是请记住,node.js 被设计成一个单线程的高性能网络服务器,所以如果你正在寻找它的用途,远离 sync-exec 之类的东西,除非你只是在启动或其他时候使用它。

这是我在一个项目中使用的方法,我目前正在工作。

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

检索 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", "") });
});
});
};

如果您使用的节点晚于7.6,并且您不喜欢回调样式,那么您还可以使用 node-util 的 promisify函数和 async / await来获得可以清晰读取的 shell 命令。下面是一个公认答案的例子,使用这种方法:

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


module.exports.getGitUser = async function getGitUser () {
// Exec output contains both stderr and stdout outputs
const nameOutput = await exec('git config --global user.name')
const emailOutput = await exec('git config --global user.email')


return {
name: nameOutput.stdout.trim(),
email: emailOutput.stdout.trim()
}
};

这还有一个额外的好处,就是对失败的命令返回被拒绝的承诺,这可以在异步代码中用 try / catch处理。

由于雷纳托的回答,我创造了一个真正基本的例子:

const exec = require('child_process').exec


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

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

规定

这需要 Node.js 7或更高版本,并支持承诺和异步/等待。

解决方案

创建一个包装函式,利用它来承诺控制 child_process.exec命令的行为。

解释

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

代码样本

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

用法

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();

样本输出

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


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

上网试试。

回复。

外部资源

承诺。

child_process.exec .

Js 支持表

您可以使用 nodejs 附带的 util 库从 exec 命令获得承诺,并可以根据需要使用该输出。使用解构将 stdout 和 stderr 存储在变量中。

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


async function lsExample() {
const {
stdout,
stderr
} = await exec('ls');
console.log('stdout:', stdout);
console.error('stderr:', stderr);
}
lsExample();

你可以使用 ShellJS软件包。
ShellJS 是在 Node.js API 之上的 Unix shell 命令的可移植(Windows/Linux/OS X)实现。
参见: < a href = “ https://www.npmjs.com/package/shelljs # Execcommand-options-callback”rel = “ nofollow norefrer”> https://www.npmjs.com/package/shelljs#execcommand——options——callback

import * as shell from "shelljs";


//usage:
//exec(command [, options] [, callback])


//example:
const version = shell.exec("node --version", {async: false}).stdout;
console.log("nodejs version", version);

下面是一个异步的等待 TypeScript 实现的公认答案:

const execute = async (command: string): Promise<any> => {
return new Promise((resolve, reject) => {
const exec = require("child_process").exec;
exec(
command,
function (
error: Error,
stdout: string | Buffer,
stderr: string | Buffer
) {
if (error) {
reject(error);
return;
}
if (stderr) {
reject(stderr);
return;
} else {
resolve(stdout);
}
}
);
});
};