web-dev-qa-db-fra.com

Utilisez child_process.execSync mais conservez la sortie dans la console

J'aimerais utiliser la méthode execSync qui a été ajoutée à NodeJS 0.12, mais conserve le résultat dans la fenêtre de la console à partir de laquelle j'ai exécuté le script Node.

Par exemple. Si j'exécute un script NodeJS comportant la ligne suivante, j'aimerais voir la sortie complète de la commande rsync "en direct" dans la console:

require('child_process').execSync('rsync -avAXz --info=progress2 "/src" "/dest"');

Je comprends que execSync renvoie le résultat de la commande et que je pourrais l’imprimer sur la console après exécution, mais de cette manière, je n’ai pas de sortie "en direct" ...

126
suamikim

Vous pouvez passer le stdio du parent au processus enfant si c'est ce que vous voulez:

require('child_process').execSync(
    'rsync -avAXz --info=progress2 "/src" "/dest"',
    {stdio: 'inherit'}
);
258
gregers

Vous pouvez simplement utiliser .toString().

var result = require('child_process').execSync('rsync -avAXz --info=progress2 "/src" "/dest"').toString();
console.log(result);

Cela a été testé sur Node v8.5.0, je ne suis pas sûr des versions précédentes. Selon @ etov , cela ne fonctionne pas sur v6.3.1 - je ne suis pas sûr de savoir entre les deux.

15
Ethan

Sauf si vous redirigez stdout et stderr comme le suggère la réponse acceptée, ceci n'est pas possible avec execSync ou spawnSync. Sans rediriger stdout et stderr, ces commandes ne renvoient que stdout et stderr une fois la commande terminée.

Pour faire cela sans rediriger stdout et stderr, vous devrez utiliser spawn pour le faire, mais c'est assez simple:

var spawn = require('child_process').spawn;

//kick off process of listing files
var child = spawn('ls', ['-l', '/']);

//spit stdout to screen
child.stdout.on('data', function (data) {   process.stdout.write(data.toString());  });

//spit stderr to screen
child.stderr.on('data', function (data) {   process.stdout.write(data.toString());  });

child.on('close', function (code) { 
    console.log("Finished with code " + code);
});

J'ai utilisé une commande ls qui répertorie les fichiers de manière récursive afin que vous puissiez le tester rapidement. Spawn prend comme premier argument le nom de l'exécutable que vous essayez d'exécuter et comme second argument, un tableau de chaînes représentant chaque paramètre que vous souhaitez transmettre à cet exécutable.

Toutefois, si vous souhaitez utiliser execSync et que vous ne pouvez pas rediriger stdout ou stderr pour une raison quelconque, vous pouvez ouvrir un autre terminal tel que xterm et lui transmettre une commande comme suit:

var execSync = require('child_process').execSync;

execSync("xterm -title RecursiveFileListing -e ls -latkR /");

Cela vous permettra de voir ce que votre commande fait dans le nouveau terminal tout en conservant l'appel synchrone.

14
Brian