为什么 ps 命令不显示整个进程列表?

为什么 ps 命令不显示整个进程列表?

如果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之后没有列出其他进程。

答案1

为什么命令 ps awx 不显示进程标识号 5646 和 5669?

因为你只是5646作为命令的一部分开始的ps awx | grep grep,并且5669作为ps awx | grep agetty命令的一部分。它们是在最初的列表之后开始的,因此在列表中不可见。两者都会运行,直到处理完ps该特定管道中进程的输入,因此它们在以后的任何列表中也不会可见。

同样,如果您ps重复运行,您将看到进程 ID 发生变化:每次运行该命令时,都会启动一个新进程。


更具体地说,所讨论的第二个过程是这样的:

5669 tty1     S+     0:00 grep --color=auto agetty

这是grep,其中已经给出了参数--color=autoagetty。这与grep中的命令匹配ps awx | grep agetty,该--color=auto标志可能来自某个别名。这不是一个agetty过程。其中一个可能会将agetty/sbin/agetty作为命令行的第一部分,如 Debian 系统中的示例所示:

1269 tty3     Ss+    0:00 /sbin/agetty --noclear tty3 linux

答案2

进程可以通过内核在微秒内来来去去fork(),无论是在内核内部还是外部。事实上,引用迈克尔·福卡拉基斯:

PID 在用户空间中不按顺序出现的原因是因为内核调度可能会在进程的 fork() 调用之间分叉一个进程。事实上,这很常见。

所以中间ps awx | grep -v grep发生ps awx | grep grep了很多事情。有新的进程和线程——它们在ps捕获它们之前就退出了。您的最后一个示例中也出现相同的逻辑ps awx | grep grep。但还要注意,grepPID 实际上可能不是最新的,因为 吉尔斯在相关答案中指出:

[p]iped 命令同时运行。当你运行 ps | grep …,ps 或 grep 是否先启动,以及无论如何它们都会继续,这取决于运气(或者是 shell 工作细节与内核内部调度程序微调相结合的问题)并发执行。

另请注意,其grep -v grep目的是从ps输出中删除自身(通常实际上建议| grep -v [g]rep在这种情况下使用,请参阅相关帖子)。

相关内容