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);
随着产卵你告诉操作系统启动进程ps
, ps
不需要等待运行,直到输出可以传送到任何地方,但可以在这之前开始,它可能只是当它试图写入其输出时被迫等待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")); });