node.js выполняет системную команду синхронно - PullRequest
159 голосов
/ 14 декабря 2010

Мне нужно в node.js function

result = execSync('node -v');

, который синхронно выполнит заданную командную строку и вернет все stdout'ed по этому тексту команды.

пс. Синхронизация неверна. Я знаю. Просто для личного пользования.

UPDATE

Теперь у нас есть решение mgutz, которое дает нам код выхода, но не стандартный вывод! Все еще жду более точного ответа.

UPDATE

mgutz обновил свой ответ и решение здесь:)
Также, как упоминалось dgo.a , существует автономный модуль exec-sync

ОБНОВЛЕНИЕ 2014-07-30

ShellJS lib прибыла. Считайте, что это лучший выбор на данный момент.


ОБНОВЛЕНИЕ 2015-02-10

ПОСЛЕДНИМ! NodeJS 0.12 поддерживает execSync изначально.
См. Официальные документы

Ответы [ 12 ]

1 голос
/ 21 мая 2013

У меня фактически была ситуация, когда мне нужно было запускать несколько команд одну за другой из сценария предварительной установки package.json таким образом, чтобы он работал как в Windows, так и в Linux / OSX, поэтому я не мог полагаться на неосновные модуль.

Так вот что я придумал:

#cmds.coffee
childproc = require 'child_process'

exports.exec = (cmds) ->
  next = ->
    if cmds.length > 0
      cmd = cmds.shift()
      console.log "Running command: #{cmd}"
      childproc.exec cmd, (err, stdout, stderr) ->
        if err? then console.log err
        if stdout? then console.log stdout
        if stderr? then console.log stderr
        next()
    else
      console.log "Done executing commands."

  console.log "Running the follows commands:"
  console.log cmds
  next()

Вы можете использовать его так:

require('./cmds').exec ['grunt coffee', 'nodeunit test/tls-config.js']

РЕДАКТИРОВАТЬ: как указывалось, это на самом деле не возвращает вывод или позволяет использовать результат команд в программе Node. Еще одна идея для этого заключается в использовании обратных вызовов LiveScript. http://livescript.net/

1 голос
/ 29 января 2012

вы можете выполнять синхронные операции оболочки в nodejs следующим образом:

var execSync = function(cmd) {

    var exec  = require('child_process').exec;
    var fs = require('fs');

    //for linux use ; instead of &&
    //execute your command followed by a simple echo 
    //to file to indicate process is finished
    exec(cmd + " > c:\\stdout.txt && echo done > c:\\sync.txt");

    while (true) {
        //consider a timeout option to prevent infinite loop
        //NOTE: this will max out your cpu too!
        try {
            var status = fs.readFileSync('c:\\sync.txt', 'utf8');

            if (status.trim() == "done") {
                var res = fs.readFileSync("c:\\stdout.txt", 'utf8');
                fs.unlinkSync("c:\\stdout.txt"); //cleanup temp files
                fs.unlinkSync("c:\\sync.txt");
                return res;
            }
        } catch(e) { } //readFileSync will fail until file exists
    }

};

//won't return anything, but will take 10 seconds to run
console.log(execSync("sleep 10")); 

//assuming there are a lot of files and subdirectories, 
//this too may take a while, use your own applicable file path
console.log(execSync("dir /s c:\\usr\\docs\\"));

РЕДАКТИРОВАТЬ - этот пример предназначен для сред Windows, при необходимости измените ваши собственные потребности Linux

...