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



我正在玩节点流和子进程。所以我想用管道模拟下一个 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) });

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

附言 - 我知道:

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

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

更新 1:
看起来 grep bash程序按预期工作,但使用 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

当您在 shell 中调用 ps au | grep sshgrep将过滤该结果以仅显示包含 ssh 的行。

如果 shell 在创建其列表之前启动grep ps则筛选之前的输出将是:

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

使用 spawn,您可以告诉操作系统ps启动进程,ps不需要等到输出可以通过管道传输到任何地方才能运行,但可以在此之前启动,它可能只会在尝试写入其输出流时被迫等待。然后你的生成grep,但在启动grep时,ps可能已经在内部创建了进程列表,并且由于它不包含grep进程。然后将ps的输出传递给 grep。但是由于缺少此输出grep ssh因此它不会显示该行。

grep是否出现在您的列表中是高度依赖操作系统的。通常,您应该假设它是否被列出是随机的。或者您需要等到ps退出并在此之后启动grep

您需要始终记住,当前操作系统具有抢占式多任务处理,并且调度程序可能会在spawn('ps', ['au']);后立即暂停节点,并在创建/请求列表后立即ps继续该过程。

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

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

相关内容

  • 没有找到相关文章

最新更新