所以,这本身并不是一个问题,只是我很好奇的事情。我正在使用 Linux Mint MATE,它是 Debian 的分支。如果我做:
ps afx | grep abcdefg
我得到:
16599 pts/3 S+ 0:00 | \_ grep --color=auto abcdefg
所以,它显示了 grep 的过程。但是,那就是后管道中的ps
:我本以为上面的代码会执行ps
,获取结果,然后将它们传递给grep
。那么为什么它grep
实际上出现在ps
结果中呢?以后不就这样了吗?我认为我错过了有关管道实际用途的一些基本知识。
答案1
这个问题是重复的,属于 unix.stackexchange.com。
总而言之,OpenGroup 的外壳命令语言文档对有关“的细节相对模糊”管道”:
管道是由控制运算符“|”分隔的一个或多个命令的序列。除最后一个命令之外的所有命令的标准输出都应连接到下一个命令的标准输入。
管道的格式为:
[!] command1 [ | command2 ...]
命令1的标准输出应连接到命令2的标准输入。命令的标准输入、标准输出或两者应被视为由管道在作为命令一部分的重定向运算符指定的任何重定向之前分配(请参阅重定向)。
如果管道不在后台(请参阅异步列表),则 shell 应等待管道中指定的最后一个命令完成,也可能等待所有命令完成。
请注意,虽然数据在管道中明显从“左到右”流动,但无法保证调度本身。
也可以看看:
答案2
日程安排根本没有多大关系。如果您考虑管道输送一项长达一小时的工作,则从第一个程序启动到完成,管道将持续保持打开状态。第二个程序与第一个程序运行的时间完全相同,并且两个程序同时完成(通常)。
换句话说,ps 不会获取输出然后将其发送到 grep - 两者同时运行,其中一个的输出输入到第二个实时。它不会等待第一个程序完成,而是收集一小时的数据,然后一次性将其全部发送给第二个程序。
尽管在实践中存在一定程度的缓冲(几百个字符),特别是当涉及多个管道时。但在大多数情况下,可以想象它们同时运行并直接相互通信。
答案3
我认为这里涉及到一些时机。
mkfifo /tmp/pipe
echo >/tmp/pipe
(shell进程被挂起)
哪个先开始并不重要,因为作者无论如何都会阻塞,直到读者打开它的结尾。因此,因为几乎任何正常的 Unix 程序都会在执行其他操作之前初始化 i/o,因此ps
会挂起,直到grep
进程建立到足以至少在该管道的读取端打开它为止。
cat </tmp/pipe &
echo >/tmp/pipe
(这次没有挂起)
grep
这个顺序意味着你总是会在那里结束。
不过,还有其他方法。
例如,如果您正在寻找 GNU 正在运行的进程的 argv0 ps
,您可以这样做:
ps -C argv0
如果您想使用grep
,这是完全可行的,但是,再次搜索 argv0:
ps -eocomm= -opid=| grep ^argv0
...这将排除每个命令的参数。
当然还有:
pgrep argv0