tutorial produccion node introduccion español javascript command node.js exec sync

javascript - produccion - node.js ejecuta el comando del sistema sincrónicamente



node js tutorial (12)

Necesito la función node.js

result = execSync(''node -v'');

que ejecutará de forma sincrónica la línea de comando dada y devolverá todo el código de comando estándar.

PD. La sincronización es incorrecta. Lo sé. Solo para uso personal.

ACTUALIZAR

¡Ahora tenemos la solución de mgutz que nos da el código de salida, pero no stdout! Todavía estoy esperando una respuesta más precisa.

ACTUALIZAR

mgutz actualizó su respuesta y la solución está aquí :)
Además, como se mencionó en dgo.a , existe exec-sync módulos independientes

ACTUALIZACIÓN 2014-07-30

ShellJS lib llegó. Considera que esta es la mejor opción por ahora.

ACTUALIZACIÓN 2015-02-10

¡AL FINAL! NodeJS 0.12 es compatible con execSync forma nativa.
Ver docs oficiales


De hecho, tuve una situación en la que necesitaba ejecutar múltiples comandos uno tras otro desde un script de preinstalación de package.json de una manera que funcionara tanto en Windows como en Linux / OSX, por lo que no podía confiar en un módulo no principal.

Así que esto es lo que se me ocurrió:

#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()

Puedes usarlo así:

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

EDITAR: como se señaló, esto en realidad no devuelve el resultado ni le permite usar el resultado de los comandos en un programa de nodo. Otra idea para eso es usar backcalls de LiveScript. http://livescript.net/


Esta es la forma más fácil que encontré:

exec-Sync : exec-sync
(No debe confundirse con execSync).
Ejecute el comando de shell de forma sincrónica. Úselo para scripts de migración, programas cli, pero no para el código de servidor normal.

Ejemplo:

var execSync = require(''exec-sync''); var user = execSync(''echo $USER''); console.log(user);


Esto no es posible en Node.js, tanto child_process.spawn como child_process.exec se construyeron desde cero para ser asincrónicos.

Para detalles, ver: https://github.com/ry/node/blob/master/lib/child_process.js

Si realmente desea tener este bloqueo, luego coloque todo lo que necesita después en una devolución de llamada, o cree su propia cola para manejar esto de forma bloqueada, supongo que podría usar Async.js para esta tarea.

O, en caso de que tengas demasiado tiempo para gastar, piratea en Node.js.


Hay un módulo excelente para el control de flujo en node.js llamado asyncblock . Si envolver el código en una función es correcto para su caso, se puede considerar la siguiente muestra:

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...''); });


Me acostumbro a implementar cosas "synchronous" al final de la función de devolución de llamada. No es muy lindo, pero funciona. Si necesita implementar una secuencia de ejecuciones de línea de comando, debe ajustar el exec en alguna función con nombre y llamarlo recursivamente. Este patrón parece ser útil para mí:

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); } }); };


Node.js (desde la versión 0.12 - por lo que por un tiempo) es compatible con execSync :

child_process.execSync(command[, options])

Ahora puede hacer esto directamente:

const execSync = require(''child_process'').execSync; code = execSync(''node -v'');

y hará lo que esperas. (Predeterminadamente para canalizar los resultados de E / S al proceso principal). Tenga en cuenta que también puede spawnSync ahora.


Puedes lograr esto usando fibras. Por ejemplo, al usar mi biblioteca Common Node , el código se vería así:

result = require(''subprocess'').command(''node -v'');



Tuve un problema similar y terminé escribiendo una extensión de nodo para esto. Puedes ver el repositorio de git. ¡Es de código abierto y gratuito y todas esas cosas buenas!

https://github.com/aponxi/npm-execxi

ExecXI es una extensión de nodo escrita en C ++ para ejecutar comandos de shell uno por uno, dando salida a la consola en tiempo real. Hay formas encadenadas y desencadenadas opcionales; lo que significa que puede optar por detener el script después de que falla un comando (encadenado), o puede continuar como si nada hubiera sucedido.

Las instrucciones de uso están en el archivo ReadMe . Siéntase libre de hacer solicitudes de extracción o enviar problemas!

EDITAR: Sin embargo, no devuelve el stdout todavía ... Simplemente los emite en tiempo real. Lo hace ahora. Bueno, acabo de lanzarlo hoy. Tal vez podamos construir sobre eso.

De todos modos, pensé que valía la pena mencionarlo.


Use el módulo ShellJS .

función exec sin proporcionar devolución de llamada.

Ejemplo:

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


Ver la biblioteca execSync .

Es bastante fácil de hacer con node-ffi . No lo recomendaría para los procesos de servidor, pero para las utilidades de desarrollo general hace las cosas. Instala la biblioteca.

npm install node-ffi

Script de ejemplo:

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

[EDITAR jun 2012: cómo obtener 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''));


puede hacer operaciones de shell sincrónicas en nodejs de esta manera:

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//"));

EDITAR: este ejemplo está destinado a entornos de Windows, si es necesario, ajústelo para sus propias necesidades de Linux