node.js同步执行系统命令

dis*_*ted 162 javascript command sync exec node.js

我需要在node.js函数中

result = execSync('node -v');
Run Code Online (Sandbox Code Playgroud)

同步执行给定的命令行并返回该命令文本的所有stdout.

PS.同步是错误的.我知道.仅供个人使用.

UPDATE

现在我们有mgutz的解决方案,它给我们退出代码,但不是stdout!仍在等待更精确的答案.

UPDATE

mgutz更新了他的答案,解决方案在这里:)
另外,正如dgo.a所提到的,有独立模块exec-sync

更新2014-07-30

ShellJS lib到了.认为这是目前最好的选择.


更新2015-02-10

最后!NodeJS 0.12原生支持execSync.
见官方文档

Ben*_*aum 133

Node.js(从版本0.12开始 - 所以有一段时间)支持execSync:

child_process.execSync(command[, options])
Run Code Online (Sandbox Code Playgroud)

您现在可以直接执行此操作:

const execSync = require('child_process').execSync;
code = execSync('node -v');
Run Code Online (Sandbox Code Playgroud)

它会做你期望的.(默认为将i/o结果传递给父进程).请注意,您spawnSync现在也可以.

  • 那是一个缓冲区,你可以将它串起来 (4认同)
  • 经过10个小时的绝望.多谢,伙计 (3认同)

mgu*_*utz 54

请参阅execSync库.

使用node-ffi相当容易.我不建议使用服务器进程,但对于一般开发实用程序,它可以完成任务.安装库.

npm install node-ffi
Run Code Online (Sandbox Code Playgroud)

示例脚本:

var FFI = require("node-ffi");
var libc = new FFI.Library(null, {
  "system": ["int32", ["string"]]
});

var run = libc.system;
run("echo $USER");
Run Code Online (Sandbox Code Playgroud)

[编辑2012年6月:如何获得STDOUT]

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'));
Run Code Online (Sandbox Code Playgroud)

  • 我想知道为什么这个简单的`execSync`不是`child_process`的一部分.我想,应该是. (8认同)
  • 你怎么会真的从这里得到任何发送到'stdout`的东西?我所能得到的只是流程退出代码 (2认同)

fal*_*lko 31

使用ShellJS模块.

exec函数没有提供回调.

例:

var version = exec('node -v').output;
Run Code Online (Sandbox Code Playgroud)

  • 请注意,在撰写本文时,文档提到同步`exec()`对于长进程来说是CPU密集型的. (2认同)
  • 选项,{silent:true} 是关键 (2认同)
  • 这做了一些事情(除了提供更短的语法),而这却没有?`const execSync = require('child_process').execSync; 代码 = execSync('节点-v');` (2认同)

nab*_*nab 23

在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...');
});
Run Code Online (Sandbox Code Playgroud)

  • @AlexeyPetrushin这里的每个问题都是关于一个目标,而不是关于实现它的特定方式.感谢downvoting. (22认同)
  • 他明确询问同步版本,而不是控制流库。 (2认同)

Ivo*_*zel 10

这是不可能的Node.js,都child_process.spawnchild_process.exec从地上爬起来是异步建成.

有关详细信息,请参阅:https://github.com/ry/node/blob/master/lib/child_process.js

如果你真的想要这个阻塞,那么把所有需要发生的事情放在回调中,或者建立你自己的队列以阻塞的方式处理它,我想你可以使用Async.js来完成这个任务.

或者,如果你有太多的时间花费,那么在Node.js中自我攻击.

  • 奇怪,因为文件系统模块有同步调用.为什么不执行? (12认同)
  • @Alfred同步FS调用主要用于在程序启动时加载配置. (4认同)
  • @IvoWetzel - tisk tisk ......我们还没学会过永远不会说不可能的事吗?;)请参阅下面的解决方案. (3认同)

dgo*_*o.a 9

这是我找到的最简单的方法:

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);
Run Code Online (Sandbox Code Playgroud)


kvz*_*kvz 7

只是补充说,即使你应该使用它们的用例很少,spawnSync/ execFileSync/ execSync也被添加到这些提交中的node.js:https://github.com/joyent/node/compare/d58c206862dc...e8df2676748e


ogr*_*ram 6

原生 Node.js 解决方案是:

const {execSync} = require('child_process');

const result = execSync('node -v'); //  this do the trick 
Run Code Online (Sandbox Code Playgroud)

请注意,某些命令返回 Buffer而不是string. 如果您string只需要添加encoding到 execSync 选项:

const result = execSync('git rev-parse HEAD', {encoding: 'utf8'});
Run Code Online (Sandbox Code Playgroud)

...并且同步执行超时也很好:

const result = execSync('git rev-parse HEAD', {encoding: 'utf8', timeout: 10000});
Run Code Online (Sandbox Code Playgroud)

  • {encoding: 'utf8'} 这就是我正在寻找的谢谢。 (2认同)

Abd*_*UMI 6

5年来我的方法是有2条线;

const { execSync } = require('child_process');
const shell = (cmd) => execSync(cmd, {encoding: 'utf8'});
Run Code Online (Sandbox Code Playgroud)

然后享受: shell('git remote -v') 或者 out = shell('ls -l') ..等等


小智 5

你可以使用纤维实现这一目标.例如,使用我的公共节点库,代码如下所示:

result = require('subprocess').command('node -v');
Run Code Online (Sandbox Code Playgroud)