我正在尝试通过命令行列出所有真实用户及其一些进程,例如:
root 73
user1 51
user2 68
我尝试了几个命令,但未能获得所写的输出。我认为这两个命令最适合仅列出用户:
awk -F':' '{ if($3 >= 1000) print $1 }' /etc/passwd
(由于 root 的 PID 为 0,因此没有列出)
awk -F':' '$2 ~ "\$" {print $1}' /etc/shadow
(需要 root 权限)
我也知道 ps 命令用于列出所有进程,但我的问题是,通过命令打印后,如何打印每个用户的具体进程数?
不确定管道是否是一种解决方案,wc -l
在这里可能也有助于计数。谢谢。
答案1
pgrep
可以打印给定用户的进程数,并xargs
针对其输入的每一行取消一个程序。将其与您的 'awk' 命令结合起来:
(echo root; awk -F: '{if($3>=1000)print $1}' /etc/passwd) | xargs -i sh -c 'echo "{} $(pgrep -cu {})"'
我正在root
手动添加到 的输出中awk
。可以使用
if($3>=1000 || $3==0)
在awk
命令中。
答案2
利用 /proc 文件系统:您的 shell 是 bash,因此:
shopt -s extglob
stat -c '%U %u' /proc/+([0-9])/ | awk '$2 >= 1000 {print $1}' | sort | uniq -c
答案3
有一种更简单的方法,使用ps
格式化选项和AWK
我们知道,默认情况下,人类用户的 UID 范围是 1000 至 65533(UID 65534 为nobody
用户)。
我们还知道ps
有格式化标志-o
,我们可以选择输出 UID 以及进程。格式如下(请注意,我这里只显示了前 5 行)
ps -eo uid,cmd | head -n 5
UID CMD
0 /sbin/init
0 [kthreadd]
0 [ksoftirqd/0]
0 [kworker/0:0H]
因此,我们可以这样做
ps -eo uid,cmd | awk '$1 >= 1000 && $1 < 65534 '
AWK 帮助我们打印第 1 列 UID 大于或等于 1000 且小于 635534 的所有行。
我的系统的示例输出(其中只有一个用户):
$ ps -eo uid,cmd | awk '$1 >= 1000 && $1 < 635534 ' | tail -n 5
1000 /usr/lib/at-spi2-core/at-spi2-registryd --use-gnome-session
1000 /usr/lib/firefox/firefox google.com
1000 ps -eo uid,cmd
1000 awk $1 >= 1000 && $1 < 635534
1000 tail -n 5
编辑
我意识到楼主想要数字人类用户所使用的流程。
如果您真正关心的是属于人类用户的进程数量,那么这里有一个快速的解决方案:
ps --no-headers -eo uid,args --sort=uid | awk '$1 >= 1000 && $1 < 65534 {counter++}; END{print counter" human processes"}'
至于我之前的解决方案,我改进了该AWK
命令,它使用基于 UID 的关联数组,并向ps
命令添加了额外的标志以包含用户名并按 UID 对输出进行排序。
ps -eo uid,euser,cmd --sort=uid | awk '$1 >= 1000 && $1 < 65534 { HUMAN++; procTotals[$1]++; if( $1 > UID ) username[$1]=$2; UID=$1 } END{ print "Out of "NR" processes, "HUMAN" belong to human users"; for(i=1000;i<=UID;i++ ) print username[i]":"procTotals[i] }'
示例输出:
xieerqi:$ ps -eo uid,euser,cmd --sort=uid | awk '$1 >= 1000 && $1 < 65534 { HUMAN++; >
Out of 215 processes, 88 belong to human users
xieerqi:84
testuser:4
为了便于阅读,以下是格式化的代码。请注意,awk 部分可以转换为带有#!/usr/bin/awk -f
shebang 行的脚本
ps -eo uid,euser,cmd --sort=uid | awk '$1 >= 1000 && $1 < 65534 {
HUMAN++; procTotals[$1]++;
if( $1 > UID ) username[$1]=$2; UID=$1
}
END{ print "Out of "NR" processes, "HUMAN" belong to human users";
for(i=1000;i<=UID;i++ )
print username[i]":"procTotals[i]
}'