如果ps awx | grep -v grep
运行该命令,则会产生以下输出。下面的列表是完整输出的最后 20 行。
4247 pts/1 Ss+ 0:00 /bin/bash
4442 ? S< 0:00 [kworker/u17:1]
4661 ? S< 0:00 [kworker/u17:3]
4731 ? S< 0:00 [kworker/u17:5]
4734 ? S 0:00 pickup -l -t fifo -u
4847 ? S< 0:00 [kworker/u17:7]
4850 ? S 0:00 [kworker/u16:3]
4878 ? S 0:00 [kworker/u16:0]
5201 ? S< 0:00 [kworker/u17:8]
5353 ? S 0:00 [kworker/0:1]
5354 ? S 0:00 [kworker/7:2]
5355 ? S 0:00 [kworker/u16:2]
5361 ? S 0:00 [kworker/4:0]
5362 tty1 Ss 0:00 -bash
5396 ? S 0:00 [kworker/6:0]
5418 ? S 0:00 [kworker/0:0]
5420 ? S 0:00 [kworker/2:2]
5431 ? S 0:00 [kworker/7:0]
5562 ? S 0:00 [kworker/4:2]
5620 tty1 R+ 0:00 ps awx
如果运行后续命令ps awx | grep grep
,则会生成以下输出。
5646 tty1 S+ 0:00 grep --color=auto grep
此外,如果ps awx | grep agetty
运行以下命令,则会显示以下输出。
5669 tty1 S+ 0:00 grep --color=auto agetty
为什么命令ps awx
不显示进程标识号 5646 和 5669?事实上,在 5620 之后没有列出其他进程。
fork()
进程可以在微秒内通过内核和外部来来去去。事实上,引用Michael Foukarakis的话:所以在
ps awx | grep -v grep
和之间ps awx | grep grep
发生了很多事情。有新的进程和线程——它们在ps
捕获它们之前就退出了。ps awx | grep grep
您和最后一个示例中出现相同的逻辑。但也要注意grep
PID 实际上可能不是最新的,因为正如 Gilles 在相关答案中指出的那样:另请注意,
grep -v grep
它旨在从ps
输出中删除自身(通常实际上建议| grep -v [g]rep
在这种情况下使用,请参阅相关帖子)。因为您只是
5646
作为命令的一部分开始的ps awx | grep grep
,并且5669
作为ps awx | grep agetty
命令的一部分。它们是在初始列表之后开始的,因此在其中不可见。两者都运行,直到它们处理了该特定管道中流程的输入ps
,因此它们在以后的任何列表中都不会可见。同样,如果您
ps
重复运行,您会看到进程 id 发生变化:每次运行命令时,都会启动一个新进程。更具体地说,第二个过程是这样的:
这是
grep
,已给出参数--color=auto
和agetty
。这与 中的grep
命令匹配ps awx | grep agetty
,--color=auto
标志可能来自某个别名。这不是一个agetty
过程。其中一个可能具有agetty
或/sbin/agetty
作为命令行的第一部分,如来自 Debian 系统的此示例: