ps au |的结果 在Node.js(使用spawn / pipe)vs shell中grep ssh不同

我正在玩节点stream和subprocess。 所以我想用pipe道模拟下一个shell命令:

ps au | grep ssh 

所以我写了下面的代码:

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

然后我运行它,但没有任何反应。 我做错了什么?

PS – 我知道:

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

我只是玩Node.js,我想了解这个例子有什么问题。

更新1:
看来,与grep bash程序按预期工作,但与grep ssh没有结果。 虽然ps au | grep ssh ps au | grep ssh给了我这个结果:

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

当你调用ps它会列出所有正在运行的进程匹配传递的选项。 这可能会寻找ps au像这样的东西:

 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 

当你打电话给ps au | grep ssh ps au | grep ssh中的shell grep会过滤那个结果,只显示包含ssh的行。

如果在ps创build列表之前grep是由shell启动的,那么在过滤之前的输出是:

 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 

grep进程将会匹配它自己的条目,因为它包含传递的参数,所以过滤后的结果是:

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

让我们看看你的代码发生了什么:

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

随着产卵你告诉操作系统启动进程psps不需要等待运行,直到输出可以传送到任何地方,但可以在这之前开始,它可能只是当它试图写入其输出时被迫等待stream。 然后你的产卵grep ,但在grep启动的时候ps可能已经在内部创build了进程列表,并导致它不包含grep进程。 ps的输出然后传递给grep。 但是,由于这个输出缺lessgrep ssh它不会显示该行。

天气grep将出现在您的列表中或不是高依赖于操作系统。 一般来说,你应该假设它是随机的,如果它被列出或没有。 或者您需要等到ps退出并在此之后启动grep

你需要时刻记住,当前的操作系统有抢先式的多任务,调度程序可能会在spawn('ps', ['au']);后立即暂停节点spawn('ps', ['au']); 并在ps创build/请求列表之后立即继续该过程。

我希望这个解释比我的评论更清楚一些。

我已经在ps之前产生了grep,现在它运行良好。 我认为这肯定是一个时间问题。 尝试这个。

 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.toString("utf8")); });