在 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
Execute and get the output of a shell command in node.js
提问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.
在线试一下。
复制。
External resources
外部资源
承诺。

