Quelle est la différence entre les trois ?
fork
Génère un processus NodeJs, avec les mêmes variables d’environnement que celui en cours. Cela permet notamment de faire du multi-thread et parallelisé une application. Un exemple concret de son utilisation arrivera dans un prochain article.
var ps = require('child_process');
var thread = ps.fork(url);
// lorsqu'on reçoit un message du thread (String)
thread.on('message', function(msg){});
// lors d'une erreur dans le thread
thread.on('error', function(err){});
// est appelé lors d'une fermeture (crash/ close)
thread.on('close', function(e, signal){});
// envoie des données vers le thread (String)
thread.send(JSON.stringify(data));
spawnchild
Démarre un processus avec un gestionnaire d'évènement, qui permet d’afficher les logs en cours. Il a la particul
var ps = require('child_process').exec;
var child = ps.spawn('find', ['-name', 'test']); // les arguments sont forcément dans un array, sans guillemet
// event stdout
child.stdout.on('data', function(data){});
child.stdout.on('close', function(data){});
// event stderr
child.stderr.setEncoding('utf8');
child.stderr.on('data', function(data){});
// à la fin du processus (kill/ close)
child.on('exit', function(exitCode, signal){});
// force kill, plusieurs flags possible récupérable dans le exit > signal
child.kill('SIGTERM');
child.kill('SIGKILL');
Une fonction légère pour parser les arguments :
var parseCommand = function(cmd){
var m, re = /("[^"]+"|[^\s"]+)/g;
var res = [];
while ((m = re.exec(cmd)) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
m[1] = m[1].replace(/"/g, '');
res.push(m[1]);
}
return res;
};
parseCommand('find . -name "test"');
// ["find", ".", "-name", "test"]
parseCommand('ffmpeg -i "trailer.mp4" -i "audio.mp3" -map 0:0 -map 1:0 -c:v libx264 "output.mp4"');
// ["ffmpeg", "-i", "trailer.mp4", "-i", "audio.mp3", "-map", "0:0", "-map", "1:0", "-c:v", "libx264", "output.mp4"]
exec
Lance un processus qui attend la fin de l’exécution avant d’appeler le callback.
var ps = require('child_process');
ps.exec('find . -name "test"', function(err, stdout, stderr){
// récupère sous format brut la sortie
});
Les données brute sont séparé par des retours à la ligne, pouvant changer d’un Os à l’autre, voici une regex pour splitté peu importe l’Os :
var CRLF = new RegExp(/(?:\r\n?|\n)/g);
var content = `abc
def
ghi`;
content.split(CRLF);
// ["abc", "def", "ghi"]