Javascript node.js 同步执行系统命令
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4443597/
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
node.js execute system command synchronously
提问by disfated
I need in node.jsfunction
我需要在node.js函数中
result = execSync('node -v');
that will synchronouslyexecute the given command line and return all stdout'ed by that command text.
这将同步执行给定的命令行并返回该命令文本的所有标准输出。
ps. Sync is wrong. I know. Just for personal use.
附:同步错误。我知道。仅供个人使用。
UPDATE
更新
Now we have mgutz's solution which gives us exit code, but not stdout! Still waiting for a more precise answer.
现在我们有了 mgutz 的解决方案,它为我们提供了退出代码,但没有标准输出!仍在等待更准确的答案。
UPDATE
更新
mgutzupdated his answer and the solution is here :)
Also, as dgo.amentioned, there is stand-alone module exec-sync
mgutz更新了他的答案,解决方案在这里:)
另外,正如dgo.a提到的,有独立模块exec-sync
UPDATE 2014-07-30
更新 2014-07-30
ShellJSlib arrived. Consider this is the best choice for now.
ShellJS库到了。考虑到这是目前最好的选择。
UPDATE 2015-02-10
更新 2015-02-10
AT LAST!NodeJS 0.12 supports execSync
natively.
See official docs
最后!NodeJS 0.12 原生支持execSync
。
查看官方文档
采纳答案by Benjamin Gruenbaum
Node.js (since version 0.12 - so for a while) supports execSync
:
Node.js(从 0.12 版开始 - 所以有一段时间)支持execSync
:
child_process.execSync(command[, options])
You can now directly do this:
您现在可以直接执行此操作:
const execSync = require('child_process').execSync;
code = execSync('node -v');
and it'll do what you expect. (Defaults to pipe the i/o results to the parent process). Note that you can also spawnSync
now.
它会做你所期望的。(默认将 i/o 结果通过管道传输到父进程)。请注意,您spawnSync
现在也可以。
回答by mgutz
See execSynclibrary.
请参阅execSync库。
It's fairly easy to do with node-ffi. I wouldn't recommend for server processes, but for general development utilities it gets things done. Install the library.
使用node-ffi相当容易。我不会推荐服务器进程,但对于一般的开发实用程序,它可以完成工作。安装库。
npm install node-ffi
Example script:
示例脚本:
var FFI = require("node-ffi");
var libc = new FFI.Library(null, {
"system": ["int32", ["string"]]
});
var run = libc.system;
run("echo $USER");
[EDIT Jun 2012: How to get STDOUT]
[编辑 2012 年 6 月:如何获得标准输出]
var lib = ffi.Library(null, {
// FILE* popen(char* cmd, char* mode);
popen: ['pointer', ['string', 'string']],
// void pclose(FILE* fp);
pclose: ['void', [ 'pointer']],
// char* fgets(char* buff, int buff, in)
fgets: ['string', ['string', 'int','pointer']]
});
function execSync(cmd) {
var
buffer = new Buffer(1024),
result = "",
fp = lib.popen(cmd, 'r');
if (!fp) throw new Error('execSync error: '+cmd);
while(lib.fgets(buffer, 1024, fp)) {
result += buffer.readCString();
};
lib.pclose(fp);
return result;
}
console.log(execSync('echo $HOME'));
回答by falko
回答by nab
There's an excellent module for flow control in node.js called asyncblock. If wrapping the code in a function is OK for your case, the following sample may be considered:
node.js 中有一个出色的流量控制模块,称为asyncblock。如果将代码包装在函数中适合您的情况,则可以考虑以下示例:
var asyncblock = require('asyncblock');
var exec = require('child_process').exec;
asyncblock(function (flow) {
exec('node -v', flow.add());
result = flow.wait();
console.log(result); // There'll be trailing \n in the output
// Some other jobs
console.log('More results like if it were sync...');
});
回答by Ivo Wetzel
This is not possible in Node.js, both child_process.spawn
and child_process.exec
were built from the ground up to be async.
这是不可能的Node.js,都child_process.spawn
和child_process.exec
从地面建是异步。
For details see: https://github.com/ry/node/blob/master/lib/child_process.js
详情见:https: //github.com/ry/node/blob/master/lib/child_process.js
If you really want to have this blocking, then put everything that needs to happen afterwards in a callback, or build your own queue to handle this in a blocking fashion, I suppose you could use Async.jsfor this task.
如果你真的想要这个阻塞,那么把之后需要发生的所有事情都放在一个回调中,或者构建你自己的队列来以阻塞的方式处理这个,我想你可以使用Async.js来完成这个任务。
Or, in case you have way too much time to spend, hack around in Node.js it self.
或者,如果您有太多时间可以花,可以自己在 Node.js 中进行破解。
回答by dgo.a
This is the easiest way I found:
这是我找到的最简单的方法:
exec-Sync: https://github.com/jeremyfa/node-exec-sync
(Not to be confused with execSync.)
Execute shell command synchronously. Use this for migration scripts, cli programs, but not for regular server code.Example:
exec-Sync: https://github.com/jeremyfa/node-exec-sync
(不要与 execSync 混淆。)
同步执行 shell 命令。将此用于迁移脚本、cli 程序,但不适用于常规服务器代码。例子:
var execSync = require('exec-sync');
var user = execSync('echo $USER');
console.log(user);
回答by kvz
Just to add that even though there are few usecases where you should use them, spawnSync
/ execFileSync
/ execSync
were added to node.js in these commits: https://github.com/joyent/node/compare/d58c206862dc...e8df2676748e
我想补充的是,即使有少数usecases,你应该使用它们,spawnSync
/ execFileSync
/execSync
添加到node.js的这些提交:https://github.com/joyent/node/compare/d58c206862dc...e8df2676748e
回答by Oleg
You can achieve this using fibers. For example, using my Common Node library, the code would look like this:
您可以使用纤维来实现这一点。例如,使用我的公共节点库,代码如下所示:
result = require('subprocess').command('node -v');
回答by Logan
I had a similar problem and I ended up writing a node extension for this. You can check out the git repository. It's open source and free and all that good stuff !
我有一个类似的问题,我最终为此编写了一个节点扩展。您可以查看 git 存储库。它是开源的,免费的,还有所有的好东西!
https://github.com/aponxi/npm-execxi
https://github.com/aponxi/npm-execxi
ExecXI is a node extension written in C++ to execute shell commands one by one, outputting the command's output to the console in real-time. Optional chained, and unchained ways are present; meaning that you can choose to stop the script after a command fails (chained), or you can continue as if nothing has happened !
ExecXI是一个用C++编写的节点扩展,用于逐条执行shell命令,将命令的输出实时输出到控制台。存在可选的链式和非链式方式;这意味着您可以选择在命令失败(链接)后停止脚本,或者您可以继续,好像什么也没发生!
Usage instructions are in the ReadMe file. Feel free to make pull requests or submit issues!
使用说明在自述文件中。随意提出请求请求或提交问题!
EDIT:However it doesn't return the stdout yet... Just outputs them in real-time.It does now.Well, I just released it today. Maybe we can build on it.
编辑:但是它还没有返回标准输出......只是实时输出它们。现在确实如此。嗯,我今天刚发布。也许我们可以以此为基础。
Anyway, I thought it was worth to mention it.
无论如何,我认为值得一提。
回答by scherka
I get used to implement "synchronous"
stuff at the end of the callback function. Not very nice, but it works. If you need to implement a sequence of command line executions you need to wrap exec
into some named function and recursively call it.
This pattern seem to be usable for me:
我习惯于"synchronous"
在回调函数的末尾实现一些东西。不是很好,但它有效。如果您需要实现一系列命令行执行,则需要包装exec
到某个命名函数中并递归调用它。这种模式似乎对我有用:
SeqOfExec(someParam);
function SeqOfExec(somepParam) {
// some stuff
// .....
// .....
var execStr = "yourExecString";
child_proc.exec(execStr, function (error, stdout, stderr) {
if (error != null) {
if (stdout) {
throw Error("Smth goes wrong" + error);
} else {
// consider that empty stdout causes
// creation of error object
}
}
// some stuff
// .....
// .....
// you also need some flag which will signal that you
// need to end loop
if (someFlag ) {
// your synch stuff after all execs
// here
// .....
} else {
SeqOfExec(someAnotherParam);
}
});
};