Résultat de ps au | grep ssh différent dans Node.js (en utilisant spawn / pipe) vs shell

Je joue avec les stream de nœuds et les processus enfants. Je veux donc émuler la prochaine commande shell avec des tubes:

ps au | grep ssh 

Alors j’ai écrit le code suivant:

 var spawn = require('child_process').spawn; var ps = spawn('ps', ['au']); var grep = spawn('grep', ['ssh']); ps.stdout.pipe(grep.stdin); grep.stdout.on('data', function(data) { console.log(data) }); 

Ensuite, je le lance, mais rien ne se passe. Qu’ai-je fait de mal?

PS – Je sais à propos de:

 require('child_process') .exec('ps au | grep ssh', function(err, stdout, stderr) { ... }). 

Je ne fais que jouer avec Node.js et je veux comprendre ce qui ne va pas dans cet exemple.

Mise à jour 1:
Il est apparu qu’avec grep bash programme fonctionnait comme prévu, mais avec grep ssh il n’y avait aucun résultat. Bien que ps au | grep ssh ps au | grep ssh me donne ce résultat:

 vagrant 11681 0.0 0.1 10464 916 pts/0 S+ 07:54 0:00 grep --color=auto ssh. 

Lorsque vous appelez ps il répertorie tous les processus en cours d’exécution correspondant aux options passées. Ce qui pourrait chercher ps au quelque chose comme ça:

 tniese 3251 0,0 0,0 2479028 3004 s000 S+ 4:06am 0:00.03 -bash root 4453 0,0 0,0 2452408 876 s004 R+ 4:06pm 0:00.00 ps au 

Lorsque vous appelez ps au | grep ssh ps au | grep ssh dans le shell grep filtrera ce résultat pour afficher uniquement les lignes contenant ssh .

Si la commande grep est lancée par le shell avant que ps crée sa liste, la sortie avant le filtrage serait:

 tniese 3251 0,0 0,0 2479028 3004 s000 S+ 4:06am 0:00.03 -bash root 4453 0,0 0,0 2452408 876 s004 R+ 4:06pm 0:00.00 ps au tniese 4478 0,0 0,0 2441988 596 s000 R+ 4:06pm 0:00.00 grep ssh 

Le processus grep correspond à sa propre entrée car il contient les parameters passés. Le résultat filtré serait donc:

 tniese 4478 0,0 0,0 2441988 596 s000 R+ 4:06pm 0:00.00 grep ssh 

Regardons ce qui se passe avec votre code:

 var spawn = require('child_process').spawn; var ps = spawn('ps', ['au']); var grep = spawn('grep', ['ssh']); ps.stdout.pipe(grep.stdin); 

Avec spawn, vous indiquez au système d’exploitation de démarrer processus ps , il n’est pas nécessaire d’attendre que la sortie soit transmise à un endroit quelconque, mais elle pourrait commencer avant, elle peut uniquement être obligée d’attendre lorsqu’elle tente d’écrire sur sa sortie. courant. Ensuite, votre grep spawn, mais au moment où grep est lancé, ps peut déjà avoir créé la liste de processus en interne et ne contient pas le processus grep . La sortie de ps est ensuite transmise à grep. Mais comme cette sortie manque de grep ssh , cette ligne ne sera pas affichée.

Si grep apparaîtra dans votre liste ou pas, cela dépendra beaucoup du système d’exploitation. En règle générale, vous devez supposer qu’il est aléatoire s’il est répertorié ou non. Ou vous devrez attendre que ps quitte et lancer grep après cela.

Vous devez toujours garder à l’esprit que le système d’exploitation actuel utilise le mode multitâche préemptif et que le planificateur peut suspendre le nœud juste après l’ spawn('ps', ['au']); de spawn('ps', ['au']); et continuez le processus juste après que ps créé / demandé la liste.

J’espère que cette explication est un peu plus claire que mon commentaire.

J’ai créé grep avant ps et maintenant cela fonctionne bien. Je pense que cela doit être une question de timing. Essaye ça.

 var spawn = require('child_process').spawn; var grep = spawn('grep', ['ssh']); var ps = spawn('ps', ['au']); ps.stdout.pipe(grep.stdin); grep.stdout.on('data', function(data) { console.log(data.toSsortingng("utf8")); });