Answers:
这应该做(在Linux下):
ps --ppid 2 -p 2 --deselect
kthreadd
(PID 2)具有PPID 0(在Linux 2.6+上),但ps
不允许过滤PPID 0;因此,此变通办法。
kthreadd
,然后构建相应的ps
调用。如何保证这个东西“总是”被称为“ kthreadd”?一个安全的解决方案将更加复杂,可以ps
正常运行并解析输出,还可以进行一些测试。
x
不起作用的标志。ps au --ppid 2 -p 2 --deselect
工作正常。
识别内核进程的一种方法是它们不使用任何用户内存,因此vsz字段为0。这也捕获了僵尸(感谢Stephane Chazelas的观察),可以根据其状态将其消除。
ps axl | awk '$7 != 0 && $10 !~ "Z"'
仅列出PID:
ps -e -o pid= -o state= -o vsize= | awk '$2 != "Z" && $3 != 0 {print $1}'
这些进程的特殊性之一是它们没有可执行文件的支持,因此可以这样做(在zsh中):
ps /proc/[0-9]*/exe(^-@:h:t)
或与任何POSIX shell:
ps -p "$(find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3 | paste -sd , -)"
那就是检查那些/proc/<pid>/exe
是文件链接的进程。
但这意味着您需要成为超级用户才能检查/proc/<pid>/exe
符号链接的状态。
编辑:僵尸进程(至少)满足相同条件,因此,如果您不希望将它们排除在外,则必须将其重新添加。喜欢:
ps -p "$(
{ find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3
ps -Ao pid=,state= | sed -n 's/ Z//p'
} | paste -sd , -)"
请注意,将ps -f
这些进程名称显示在方括号中并不是因为它们是内核进程,而是因为它们有一个空的argv[]
(因此ps显示的是进程名称,而不是argv[0]
那里)。您可以使用户空间的进程也为空argv[]
,也可以使进程名argv[0]
的形式为,[some-string]
因此ps
基于这些方括号过滤输出不是万无一失的选择。
zsh
语法。第二种是标准POSIX sh
(以及ps
和find
和cut
与和paste
)语法。当然/proc
不是POSIX指定的。
wc -l
)。好吧,那我会接受Hauke Laging的回答,并给您点赞。;)
您也可以仅解析ps
输出并查找不在方括号中的进程名称:
ps aux | awk '$NF!~/^\[.+\]$/'
awk -F: '$7 ~ home { print $1 }' /etc/passwd
-但是您仍将获得提及任何此类用户名的进程,并且将临时文件保留在身边。我将撤回我的赞成票,但这只是因为您的第三个解决方案是合理的。
$NF
是ps aux
输出中命令行的最后一个字。非内核进程可以在[...]
那里。正如我在回答中所说的,[xxx]
表示法不是因为它们是内核进程,而是因为它们没有命令行(没有参数),这也允许非内核进程使用。
对于在busybox中尝试了此功能ps
且简化程度大且输出不同的任何人,这种Gilles很好的答案很好用:
ps -o pid,user,comm,vsz,stat | awk '$4 != 0 && $5 !~ "Z"'
根据Gilles的回答,这里的方法是查找不使用任何用户内存的进程(vsz col == 0),并过滤掉僵尸进程(status col不是'Z')。
只要从1开始的awk字段号进行了相应调整,就可以轻松调整输出列。通过输入伪造的值来查看ps可用的选项,它将告诉您。例如:
$ ps -o foo
ps: bad -o argument 'foo', supported arguments: user,group,comm,args,pid,ppid,pgid,tty,vsz,stat,rss
如果您只需要计数... 我同样需要过滤内核与用户进程,但我只需要每个计数。这是我的解决方案:
ps -eo vsize | awk '{p[$1==0]++} END {printf "%-16s %6d\n%-16s %6d\n%-16s %6d\n", "Kernel processes", p[1], "User processes", p[0], "Total processes", p[0]+p[1]}'
样本输出:
Kernel processes 353
User processes 52
Total processes 405
说明:我正在使用VSZ = 0进程可以假定为内核进程的技巧。因此,通过awk
,我评估了VSZ(来自ps -eo vsize
)的比较,是否等于零。比较的结果将是布尔值0或1。我创建一个数组p[]
,然后在进程列表中运行,如果它是内核进程,则我递增p[1]++
。否则,作为用户进程,我将递增p[0]++
。在所有增量之后,我标记并打印END { }
块中p [0]和p [1]的值(即计数)。
我的朋友,您要找的不是ps
,而是pstree
。
首先,确定第一个内核进程。它的PID通常在不带systemd的系统上为1,而带systemd的系统上为2。
然后使用以下命令:
$ pstree -p <1 or 2> | grep -o '([0-9]\+)' | grep -o '[0-9]\+'
所选答案(带有✅的答案)正在使用另一个命令:
$ ps --ppid 2 -p 2 --deselect
该ps
命令的问题在于它仅包括直接子代,而不包括所有后代。该pstree
命令包括所有后代。您可以比较和计算这两个命令的输出(一种简单的方法是使用| wc
)进行验证。
kthreadd
始终使用PID 2?