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 de script de café. Mais stdout ne sera jamais affiché dans la console, car la commande ne se termine jamais (à cause de l'option -w de coffee). Si j'exécute la commande directement à partir de la console, le message suivant s'affiche:
18:05:59 - compiled my_file.coffee
Ma question est: est-il possible d'afficher ces messages avec le noeud exec.js? Si oui comment? !
Merci
N'utilisez pas exec
. Utilisez spawn
qui est un objet EventEmmiter
. Ensuite, vous pouvez écouter les événements stdout
/stderr
(spawn.stdout.on('data',callback..)
) tels 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 la sortie en mémoire tampon et la renvoie généralement à la fin de l'exécution de la commande.
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
la sortie standard du processus enfant vers la sortie principale.
coffeeProcess.stdout.pipe(process.stdout);
OU hériter de stdio en utilisant spawn
spawn('coffee -cw my_file.coffee', { stdio: 'inherit' });
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, qui utilise spawn
et le { stdio: 'inherit' }
option . Il semble produire la sortie la plus précise, par exemple lors de l’affichage des informations de progression d’un git clone
.
Faites simplement ceci:
var spawn = require('child_process').spawn;
spawn('coffee', ['-cw', 'my_file.coffee'], { stdio: 'inherit' });
Nous remercions @MorganTouvereyQuilling de l'avoir signalé dans ce commentaire .
J'aimerais simplement ajouter qu'un petit problème avec la sortie des chaînes de mémoire tampon d'un processus généré avec console.log()
est qu'il ajoute des nouvelles lignes, ce qui peut étendre la sortie de votre processus généré sur des lignes supplémentaires. Si vous exportez stdout
ou stderr
avec process.stdout.write()
au lieu de console.log()
, vous obtiendrez la sortie de la console du processus généré 'en l'état' .
J'ai vu cette solution ici: Node.js: imprimer sur console sans nouvelle ligne?
J'espère que cela aidera quelqu'un qui utilise la solution ci-dessus (ce qui est excellent pour les sorties en direct, même si cela provient de la documentation).
Inspiré par la réponse de Nathanael Smith et le 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);
J'ai trouvé utile d'ajouter un script d'exécution personnalisé à mes utilitaires qui effectuent cette opération.
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')
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, data
aura plusieurs lignes. L'en-tête oldSchoolMakeBuild
apparaît alors une fois pour plusieurs lignes. Mais cela ne m'a pas dérangé assez pour le changer.
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 au nœud. stdout étant un flux, les événements "data", "end" et autres sont présents. 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.).
afin que vous puissiez résoudre votre problème en utilisant child_process.spawn comme utilisé 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());
});