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")); });