J'ai besoin de node.js fonction
result = execSync('node -v');
cela va de manière synchrone exécuter la ligne de commande donnée et renvoyer tous les caractères stdout'ed de ce texte de commande.
ps. La synchronisation est fausse. Je connais. Juste pour un usage personnel.
UPDATE
Nous avons maintenant la solution de mgutz qui nous donne le code de sortie, mais pas la sortie standard! J'attends toujours une réponse plus précise.
UPDATE
mgutz a mis à jour sa réponse et la solution est la suivante :)
En outre, comme dgo.a est mentionné, il existe un module autonome exec-sync
MISE À JOUR 2014-07-30
ShellJS lib est arrivé. Considérez que c'est le meilleur choix pour le moment.
MISE À JOUR 2015-02-10
ENFIN! NodeJS 0.12 supporte execSync
de manière native.
Voir plus haut docs
Node.js (depuis la version 0.12 - donc pendant un moment) supporte execSync
:
child_process.execSync(command[, options])
Vous pouvez maintenant faire ceci directement:
const execSync = require('child_process').execSync;
code = execSync('node -v');
et ça fera ce que vous attendez. (Par défaut, les résultats d'entrée/sortie sont redirigés vers le processus parent). Notez que vous pouvez également spawnSync
maintenant.
Voir execSync bibliothèque.
C'est assez facile à faire avec node-ffi . Je ne le recommanderais pas pour les processus de serveur, mais pour les utilitaires de développement généraux, cela permet de faire avancer les choses. Installez la bibliothèque.
npm install node-ffi
Exemple de script:
var FFI = require("node-ffi");
var libc = new FFI.Library(null, {
"system": ["int32", ["string"]]
});
var run = libc.system;
run("echo $USER");
[EDIT juin 2012: Comment obtenir 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'));
Il y a un excellent module de contrôle de flux dans node.js appelé asyncblock . Si insérer le code dans une fonction est acceptable pour votre cas, l'exemple suivant peut être pris en compte:
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...');
});
Ce n'est pas possible dans Node.js, child_process.spawn
et child_process.exec
ont été construits à partir du sol pour être asynchrones.
Pour plus de détails, voir: https://github.com/ry/node/blob/master/lib/child_process.js
Si vous voulez vraiment avoir ce blocage, puis mettez tout ce qui doit se passer après dans un rappel, ou créez votre propre file d'attente pour le gérer de manière bloquante, je suppose que vous pourriez utiliser Async.js pour cette tâche.
Ou, au cas où vous auriez trop de temps à dépenser, lancez-vous dans Node.js.
C'est le moyen le plus simple que j'ai trouvé:
exec-Sync : https://github.com/jeremyfa/node-exec-sync
(À ne pas confondre avec execSync.)
Exécuter la commande shell de manière synchrone. Utilisez cette option pour les scripts de migration et les programmes CLI, mais pas pour le code serveur standard.Exemple:
var execSync = require('exec-sync');
var user = execSync('echo $USER');
console.log(user);
Juste pour ajouter que même s'il y a peu de cas d'utilisation où vous devriez les utiliser, spawnSync
/execFileSync
/execSync
ont été ajoutés à node.js dans ces commits: https://github.com/joyent/node/compare/d58c206862dc...e8df2676748e
Vous pouvez y parvenir en utilisant des fibres. Par exemple, en utilisant ma bibliothèque Common Node _ , le code ressemblerait à ceci:
result = require('subprocess').command('node -v');
Je m'habitue à implémenter des éléments "synchronous"
à la fin de la fonction de rappel. Pas très gentil, mais ça marche. Si vous devez implémenter une séquence d'exécutions en ligne de commande, vous devez envelopper exec
dans une fonction nommée et l'appeler de manière récursive. Ce modèle semble être utilisable pour moi:
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);
}
});
};
J'ai eu un problème similaire et j'ai fini par écrire une extension de noeud pour cela. Vous pouvez consulter le référentiel git. C'est open source et gratuit et tout ce qui est bon!
https://github.com/aponxi/npm-execxi
ExecXI est une extension de noeud écrite en C++ permettant d'exécuter les commandes Shell une par une, générant le résultat de la commande sur la console en temps réel. Des manières facultatives chaînées et non chaînées sont présentes; ce qui signifie que vous pouvez choisir d'arrêter le script après l'échec d'une commande (chaînée), ou vous pouvez continuer comme si rien ne s'était passé!
Les instructions d'utilisation figurent dans le fichier fichier Lisez-moi . N'hésitez pas à faire des demandes de tirage ou à soumettre des problèmes!
EDIT: Cependant, il ne retourne pas encore la sortie standard ... Il suffit de les sortir en temps réel. C'est le cas maintenant Eh bien, je viens de le publier aujourd'hui. Peut-être pourrions-nous en tirer parti.
Quoi qu'il en soit, j'ai pensé qu'il valait la peine de le mentionner.
vous pouvez effectuer des opérations Shell synchrones dans nodejs comme ceci:
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\\"));
EDIT - cet exemple est destiné aux environnements Windows, ajustez-le si nécessaire
En réalité, j’ai dû exécuter plusieurs commandes l’un après l’autre à partir d’un script de préinstallation package.json d’une manière qui fonctionnerait à la fois sous Windows et sous Linux/OSX. Je ne pouvais donc pas compter sur un module non essentiel.
Alors voici ce que je suis venu avec:
#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()
Vous pouvez l'utiliser comme ceci:
require('./cmds').exec ['grunt coffee', 'nodeunit test/tls-config.js']
EDIT: comme indiqué, cela ne retourne pas la sortie et ne vous permet pas d'utiliser le résultat des commandes dans un programme Node. Une autre idée consiste à utiliser des backcalls LiveScript. http://livescript.net/