Je vois comment diriger des trucs ensemble en utilisant des flux Node.js, mais comment canaliser plusieurs scripts ensemble en utilisant le Unix |
, étant donné que certains de ces scripts peuvent être asynchrones?
$ ./a.js | ./b.js
Exemple:
a.js (chmod 0755)
#!/usr/bin/env node
setTimeout(function(){
console.log(JSON.stringify({ foo: 'bar' }));
}, 10);
b.js (chmod 0755)
#!/usr/bin/env node
console.log(process.argv);
Voici la sortie:
$ ./a.js | ./b.js
[ 'node', '/Users/viatropos/tests/b.js' ]
events.js:72
throw er; // Unhandled 'error' event
^
Error: write EPIPE
at errnoException (net.js:883:11)
at Object.afterWrite (net.js:700:19)
À première vue, il semble qu'il y ait beaucoup de problèmes, donc vous ne savez pas trop par où commencer. Existe-t-il un moyen de faire fonctionner cela? L'objectif final est de pouvoir prendre le console.log
sortie de ./a.js
et l'utiliser dans ./b.js
. La raison en est que la plupart du temps, ces scripts seront exécutés un par un, mais il serait parfois agréable de pouvoir les assembler, donc idéalement le système devrait être capable de gérer les deux cas.
Le problème est que votre b.js
Se termine immédiatement et ferme son standard dans, ce qui provoque une erreur dans a.js
, Car son standard a été désactivé et vous n'avez pas géré cette possibilité. Vous avez deux options: gérer la fermeture stdout dans a.js
Ou accepter l'entrée dans b.js
.
Correction de a.js
:
process.on("SIGPIPE", process.exit);
Si vous ajoutez cette ligne, elle abandonnera quand personne ne lira plus sa sortie. Il y a probablement de meilleures choses à faire sur SIGPIPE selon ce que fait votre programme, mais la clé est d'arrêter console.log
.
Correction de b.js
:
#!/usr/bin/env node
var stdin = process.openStdin();
var data = "";
stdin.on('data', function(chunk) {
data += chunk;
});
stdin.on('end', function() {
console.log("DATA:\n" + data + "\nEND DATA");
});
Bien sûr, vous n'avez avez pour rien faire avec ces données. Leur clé est d'avoir quelque chose qui maintient le processus en cours; si vous y accédez, stdin.on('data', fx)
semble être une chose utile à faire.
N'oubliez pas que l'un ou l'autre de ces éléments empêchera cette erreur. Je m'attends à ce que le second soit le plus utile si vous prévoyez de canaliser entre les programmes.