J'ai ce script simple:
var exec = require('child_process').exec;
exec('coffee -cw my_file.coffee', function(error, stdout, stderr) {
console.log(stdout);
});
où j'exécute simplement une commande pour compiler un fichier coffee-script. Mais stdout ne s'affiche jamais dans la console, car la commande ne se termine jamais (à cause de l'option -w de coffee). Si j'exécute la commande directement depuis la console, je reçois un message comme celui-ci:
18:05:59 - compiled my_file.coffee
Ma question est: est-il possible d'afficher ces messages avec l'exec de node.js? Si oui comment? !
Merci
node.js
coffeescript
Mravey
la source
la source
Réponses:
N'utilisez pas
exec
. Utilisezspawn
qui est unEventEmmiter
objet. Ensuite, vous pouvez écouterstdout
/stderr
events (spawn.stdout.on('data',callback..)
) au fur et à mesure qu'ils se produisent .À partir de la documentation NodeJS:
var spawn = require('child_process').spawn, ls = spawn('ls', ['-lh', '/usr']); ls.stdout.on('data', function (data) { console.log('stdout: ' + data.toString()); }); ls.stderr.on('data', function (data) { console.log('stderr: ' + data.toString()); }); ls.on('exit', function (code) { console.log('child process exited with code ' + code.toString()); });
exec
met en mémoire tampon la sortie et la renvoie généralement lorsque la commande a fini de s'exécuter.la source
flush(stdout);
en C) afin de déclencher des événements dans Node.js.exec
renverra également un objet ChildProcess qui est un EventEmitter.var exec = require('child_process').exec; var coffeeProcess = exec('coffee -cw my_file.coffee'); coffeeProcess.stdout.on('data', function(data) { console.log(data); });
OU
pipe
le stdout du processus enfant vers le stdout principal.coffeeProcess.stdout.pipe(process.stdout);
OU hériter de stdio en utilisant spawn
spawn('coffee -cw my_file.coffee', { stdio: 'inherit' });
la source
pipe
:coffeeProcess.stdout.pipe(process.stdout);
spawn(cmd, argv, { stdio: 'inherit' })
. Voir nodejs.org/api/child_process.html#child_process_options_stdio pour différents exemples.spawn
avecstdio: 'inherit'
. Il produit une sortie plus précise queexec
et pipingstdout
/stderr
, par exemple lors de l'affichage des informations de progression d'un fichiergit clone
.Il existe déjà plusieurs réponses, mais aucune d'entre elles ne mentionne la meilleure (et la plus simple) façon de le faire, à savoir l'utilisation
spawn
et l'{ stdio: 'inherit' }
option . Il semble produire la sortie la plus précise, par exemple lors de l'affichage des informations de progression à partir d'un fichiergit clone
.Faites simplement ceci:
var spawn = require('child_process').spawn; spawn('coffee', ['-cw', 'my_file.coffee'], { stdio: 'inherit' });
Merci à @MorganTouvereyQuilling pour l'avoir signalé dans ce commentaire .
la source
stdio: "inherit"
préserve ce formatage alors que cechild.stdout.pipe(process.stdout)
n'est pas le cas.Inspiré de la réponse de Nathanael Smith et du commentaire d'Eric Freese, cela pourrait être aussi simple que:
var exec = require('child_process').exec; exec('coffee -cw my_file.coffee').stdout.pipe(process.stdout);
la source
ls
mais échoue pour des commandes plus complexes telles quenpm install
. J'ai même essayé de raccorder à la fois stdout et stderr à leurs objets de processus respectifs.spawn(command, args, { stdio: 'inherit' })
, comme suggéré ici, stackoverflow.com/questions/10232192/…Je voudrais simplement ajouter qu'un petit problème avec la sortie des chaînes de tampon à partir d'un processus généré avec
console.log()
est qu'il ajoute des nouvelles lignes, ce qui peut répartir la sortie de votre processus généré sur des lignes supplémentaires. Si vous sortezstdout
oustderr
avecprocess.stdout.write()
au lieu deconsole.log()
, alors vous obtiendrez la sortie de la console du processus généré «tel quel».J'ai vu cette solution ici: Node.js: impression sur console sans nouvelle ligne de fin?
J'espère que cela aidera quelqu'un à utiliser la solution ci-dessus (qui est excellente pour la sortie en direct, même si elle provient de la documentation).
la source
spawn(command, args, { stdio: 'inherit' })
, comme suggéré par @MorganTouvereyQuilling ici stackoverflow.com/questions/10232192/…J'ai trouvé utile d'ajouter un script d'exécution personnalisé à mes utilitaires qui le font.
utilities.js
const { exec } = require('child_process') module.exports.exec = (command) => { const process = exec(command) process.stdout.on('data', (data) => { console.log('stdout: ' + data.toString()) }) process.stderr.on('data', (data) => { console.log('stderr: ' + data.toString()) }) process.on('exit', (code) => { console.log('child process exited with code ' + code.toString()) }) }
app.js
const { exec } = require('./utilities.js') exec('coffee -cw my_file.coffee')
la source
Après avoir examiné toutes les autres réponses, je me suis retrouvé avec ceci:
function oldSchoolMakeBuild(cb) { var makeProcess = exec('make -C ./oldSchoolMakeBuild', function (error, stdout, stderr) { stderr && console.error(stderr); cb(error); }); makeProcess.stdout.on('data', function(data) { process.stdout.write('oldSchoolMakeBuild: '+ data); }); }
Parfois, il y
data
aura plusieurs lignes, donc l'en-oldSchoolMakeBuild
tête apparaîtra une fois pour plusieurs lignes. Mais cela ne m'a pas assez dérangé pour le changer.la source
child_process.spawn renvoie un objet avec les flux stdout et stderr. Vous pouvez appuyer sur le flux stdout pour lire les données que le processus enfant renvoie à Node. stdout étant un flux a les "données", la "fin" et d'autres événements que les flux ont. spawn est mieux utilisé lorsque vous souhaitez que le processus enfant renvoie une grande quantité de données à Node - traitement d'image, lecture de données binaires, etc.
vous pouvez donc résoudre votre problème en utilisant child_process.spawn comme ci-dessous.
var spawn = require('child_process').spawn, ls = spawn('coffee -cw my_file.coffee'); ls.stdout.on('data', function (data) { console.log('stdout: ' + data.toString()); }); ls.stderr.on('data', function (data) { console.log('stderr: ' + data.toString()); }); ls.on('exit', function (code) { console.log('code ' + code.toString()); });
la source
Voici une fonction d'assistance asynchrone écrite en manuscrit qui semble faire l'affaire pour moi. Je suppose que cela ne fonctionnera pas pour les processus de longue durée, mais pourrait toujours être utile pour quelqu'un?
import * as child_process from "child_process"; private async spawn(command: string, args: string[]): Promise<{code: number | null, result: string}> { return new Promise((resolve, reject) => { const spawn = child_process.spawn(command, args) let result: string spawn.stdout.on('data', (data: any) => { if (result) { reject(Error('Helper function does not work for long lived proccess')) } result = data.toString() }) spawn.stderr.on('data', (error: any) => { reject(Error(error.toString())) }) spawn.on('exit', code => { resolve({code, result}) }) }) }
la source