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"]