Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ps au| grep ssh在Node.js(使用spawn/pipe)和shell中的结果不同_Javascript_Node.js_Pipe_Child Process - Fatal编程技术网

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

Javascript ps au| grep ssh在Node.js(使用spawn/pipe)和shell中的结果不同,javascript,node.js,pipe,child-process,Javascript,Node.js,Pipe,Child Process,我正在处理节点流和子进程。因此,我想用管道模拟下一个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) {

我正在处理节点流和子进程。因此,我想用管道模拟下一个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之前就已经产生了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")); 
});

当您调用
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
当您在shell中调用
ps au | grep ssh
时,
grep
将过滤该结果,以仅显示包含
ssh
的行

如果在
ps
创建列表之前,shell启动了
grep
,则过滤前的输出将是:

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
tniese  4478   0,0  0,0  2441988    596 s000  R+    4:06pm   0:00.00 grep ssh
grep
进程将匹配它自己的条目,因为它包含传递的参数,因此过滤结果将是:

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
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
无需等待运行,直到输出可以通过管道传输到任何地方,但可以在此之前启动,它可能只有在尝试写入its输出流时才被迫等待。然后您的spawn
grep
,但在启动
grep
ps
可能已经在内部创建了进程列表,因此它不包含
grep
进程。然后将
ps
的输出传递给grep。但由于该输出缺少grepsh
grepsh
,因此它不会显示该行

grep是否会出现在您的列表中取决于操作系统。通常,您应该假设它是随机的,无论它是否列出。或者您需要等到
ps
退出,然后启动
grep

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


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

你的代码对我来说很有用(除了
bash
而不是
ssh
)。如果在shell提示符下执行
ps au | grep ssh
,是否看到输出?@mscdex-Hmm,很有趣。它使用
bash
命令工作(结果与
ps au | grep bash
相同)。使用
ssh
没有结果。尽管
ps au | grep ssh
给我结果:
vagrant 11681 0.0 0.1 10464 916 pts/0 S+07:54 0:00 grep--color=auto ssh
。这些nodejs脚本运行在哪个用户ID下?可能没有人或web用户,而不是您的登录用户?我认为存在某种时间问题,因为我有时可以看到输出,但并不总是如此。@Paul我从控制台调用此脚本:
node pipe\u example.js
使用vagrant(使用OS Linux Ubuntu 14.04的虚拟机)。所以用户-
vagrant
,用户id-
1000
。一年,它工作了!但我不明白为什么?对我来说,这完全不合逻辑。我会等一会儿——也许有人知道一些关于它的事情,也许它是一个功能,而不是一个bug。如果没有-将您的答案标记为已接受,并在节点github repositoryYear中创建问题。我明白你的意思。我想没有人能解释得更好,所以请把你的回答标记为已接受。但最后一个问题是:您不认为节点必须为stdout流中的
ps
命令缓冲结果数据吗?或者至少有这样做的选项?创建for节点。让核心团队来决定这种行为的正确性。@alexpods我假设节点或操作系统本身已经为生成的进程的stdout进行了缓冲,但这对您描述的问题并不重要。只要
ps
是在
grep
之前生成的,则
grep
很可能不会出现在列表中,而不会出现在列表中,但这取决于系统的调度程序会发生什么。对于命令
ps au | grep ssh
shell很可能会在生成
ps
之前生成
grep
,这就是为什么您会在shell中看到
grep
。这两种行为都没有错。