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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 12:26:22  来源:igfitidea点击:

node.js execute system command synchronously

javascriptcommandnode.jsexecsync

提问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 execSyncnatively.
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 spawnSyncnow.

它会做你所期望的。(默认将 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

Use ShellJSmodule.

使用ShellJS模块。

execfunction without providing callback.

exec函数而不提供回调。

Example:

例子:

var version = exec('node -v').output;

回答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.spawnand child_process.execwere built from the ground up to be async.

这是不可能的Node.js,都child_process.spawnchild_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/ execSyncwere 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 execinto 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);
        }
    });
};