为什么 `ps -x | grep foo` 包含 grep 命令?

为什么 `ps -x | grep foo` 包含 grep 命令?

我知道(通常)包括 grep 过程,我知道添加| grep -v grep或 grepping[f]oo会阻止它,但我的问题更多的是关于操作顺序。

例如,在这个虚构的例子中,我看到了几个 grep 进程:

% ps -x | grep login | grep login | grep login | grep login
 2475 ??         0:00.03 /usr/libexec/loginitemregisterd
 2115 ttys004    0:00.04 login -fp jasonerickson
29715 ttys004    0:00.00 grep login
29716 ttys004    0:00.00 grep login
29717 ttys004    0:00.00 grep login
29718 ttys004    0:00.00 grep login

这告诉我ps -x必须执行最后的在该行中,因为它列出了所有后续的 grep 命令。但是,它并不一致。有时它会列出 4 个或 3 个或 2 个甚至没有 grep 进程。这对我来说意味着它不是总是最后的。

这是怎么回事?

答案1

正如 Bravo 指出的那样,Linux 中的管道不是文件,而是动态的。因此ps -x | grep login实际上会同时启动两个程序,这样其中一个程序可以关闭管道,而另一个程序可以捕获。它不是确定性的,您设计的示例并不总是显示四个实例,原因是实例可能在管道中有要执行的操作之前不会启动;或者在读取进程列表grep时,相关实例可能尚未完全启动。ps

答案2

Unix 是一个多任务操作系统。它不会首先或最后启动 ps。它会并行启动管道中的所有任务。有些任务可能先完成或在 ps 启动后启动,这就是竞争的原因,这会使结果略微不确定。

基本上,这里没有操作顺序。管道是数据流,而不是数学公式。

Unix 中管道的优点在于第二个程序可以在第一个程序完成之前开始处理输入,因此没有必要在将数据流提供给管道中的下一个程序之前收集并存储在内存(或磁盘)中。

相关内容