如何编写Bash脚本显示各用户进程及对应内存占用情况
实现按用户分组显示进程及内存占用的Bash脚本
方案一:用awk一次性高效处理(推荐)
这种方法通过ps输出结构化字段,再用awk完成过滤、分组和格式化,避免多次调用外部命令,效率更高。
#!/bin/bash # 打印对齐的表头 printf "%-8s %-20s %-8s\n" "USER" "PROCESS" "MEMORY" # 提取用户、UID、进程命令、内存数据,awk处理分组和格式 ps -eo user,uid,cmd,rss --no-headers | awk ' # 过滤规则:UID为root(0)或普通用户(>=1000),排除nobody用户 $2 == 0 || ($2 >= 1000 && $1 != "nobody") { # 按用户分组存储进程和内存,用|分隔字段、换行分隔进程 user_procs[$1] = user_procs[$1] $3 "|" $4 "\n" } END { # 遍历每个符合条件的用户 for (user in user_procs) { split(user_procs[user], procs, "\n") # 处理第一个进程,显示用户名 split(procs[1], info, "|") printf "%-8s %-20s %6sKB\n", user, info[1], info[2] # 处理后续进程,缩进用户名位置 for (i=2; i<length(procs); i++) { if (procs[i] != "") { split(procs[i], info, "|") printf "%-8s %-20s %6sKB\n", "", info[1], info[2] } } } } '
方案二:基于你的现有代码逻辑改进
如果你想保留先提取用户列表再遍历的思路,可以用下面的脚本,逻辑更直观:
#!/bin/bash # 获取符合条件的用户列表(保留你原有的过滤逻辑) runningUsers=$(ps aux | awk '{print $1}' | sort | uniq | perl -e 'for (<>) { chomp; $u = (getpwnam($_))[2]; print "$_\n" if (($u >= 1000 || $u == 0) && ($_ =~ /[[:alpha:]]/ && $_ ne "nobody")) }') # 打印表头 printf "%-8s %-20s %-8s\n" "USER" "PROCESS" "MEMORY" # 遍历每个用户,输出其进程和内存 for user in $runningUsers; do # 获取当前用户的进程命令和内存(RSS,单位KB) ps -u "$user" -o cmd,rss --no-headers | while read -r cmd rss; do # 标记是否为该用户的第一个进程 if [[ -z $first_proc ]]; then printf "%-8s %-20s %6sKB\n" "$user" "$cmd" "$rss" first_proc=1 else printf "%-8s %-20s %6sKB\n" "" "$cmd" "$rss" fi done # 重置标记,处理下一个用户 unset first_proc done
关键说明
- 内存数据用
RSS(常驻内存大小),单位为KB,这是ps默认提供的直观内存指标。 - 用
printf的格式控制符(如%-8s、%6s)保证输出列对齐,和你期望的格式一致。 - 方案一通过
awk的数组分组,无需循环调用ps,性能更优;方案二逻辑拆分更清晰,适合调试和理解。
内容的提问来源于stack exchange,提问作者mitas1c
相关产品推荐
相关产品推荐

