Shell 脚本 / 命令文档
Shell编程实战
概述
编写内存使用TOP10监控脚本
课程目标
通过本课程,你将学会:
理解Linux进程内存管理机制
掌握ps命令的高级用法
学会数据处理和排序技巧
编写实用的系统监控脚本
1. 内存指标理解
| 指标 | 说明 | 选择建议 |
|---|---|---|
| RSS | 实际物理内存使用量(Resident Set Size) | 推荐使用 |
| VSZ | 虚拟内存大小(包含共享库) | 参考指标 |
| %MEM | 占系统总内存的百分比 | 推荐使用 |
提示:本教程使用RSS作为排序依据,因为它反映了进程实际占用的物理内存。
2. 关键命令
| 命令 | 作用 |
|---|---|
| ps aux | 显示所有进程详细信息 |
| sort -k4 -rn | 按第4列数值逆序排序 |
| head -n 10 | 取前10行 |
| awk | 文本处理和格式化 |
编写思路
使用 ps aux 获取所有进程的详细信息,包括内存使用情况
使用 grep -v "^USER" 或 sed '1d' 去掉ps输出的标题行
按照内存使用量(RSS或%MEM)进行降序排序
使用 head 命令获取排序后的前10条记录
使用 awk 或 printf 美化输出结果
方案一:简洁版(一行命令)
Shell Script
#!/bin/bash # 按RSS内存使用量排序,显示TOP10 ps aux | grep -v "^USER" | sort -k6 -rn | head -n 10
注意:ps aux输出中,第6列是RSS(单位KB),第4列是%MEM
方案二:完整版(带格式化输出)
memory_top10.sh
#!/bin/bash
# ======================================
# 功能:显示内存使用TOP10的进程
# 作者:Linux Expert
# 日期:2025-10-22
# ======================================
# 设置颜色变量(可选)
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 打印标题
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} 内存使用TOP10进程监控报告${NC}"
echo -e "${GREEN} 生成时间: $(date '+%Y-%m-%d %H:%M:%S')${NC}"
echo -e "${GREEN}========================================${NC}"
echo
# 获取系统总内存(MB)
TOTAL_MEM=$(free -m | awk 'NR==2{print $2}')
echo -e "系统总内存: ${YELLOW}${TOTAL_MEM}MB${NC}"
echo
# 打印表头
printf "%-8s %-10s %-6s %-8s %-s\n" "USER" "PID" "%MEM" "RSS(MB)" "COMMAND"
echo "----------------------------------------------------------------"
# 获取并格式化TOP10进程信息
ps aux | grep -v "^USER" | sort -k6 -rn | head -n 10 | \
while read user pid cpu mem vsz rss tty stat start time cmd; do
# 将RSS从KB转换为MB
rss_mb=$(awk "BEGIN {printf \"%.2f\", $rss/1024}")
# 截取命令名(最多40个字符)
cmd_short=$(echo $cmd | cut -c1-40)
# 格式化输出
printf "%-8s %-10s %-6s %-8s %-s\n" \
"$user" "$pid" "$mem%" "$rss_mb" "$cmd_short"
done
echo
echo -e "${GREEN}========================================${NC}"方案三:高级版(支持参数和日志)
memory_top10_advanced.sh
#!/bin/bash
# 高级版本:支持自定义TOP数量和日志记录
# 默认值
TOP_N=10
LOG_FILE=""
# 参数解析
while getopts "n:l:h" opt; do
case $opt in
n)
TOP_N=$OPTARG
;;
l)
LOG_FILE=$OPTARG
;;
h)
echo "Usage: $0 [-n number] [-l logfile]"
echo " -n: 显示TOP N个进程(默认10)"
echo " -l: 指定日志文件路径"
exit 0
;;
\?)
echo "Invalid option: -$OPTARG"
exit 1
;;
esac
done
# 输出函数
output() {
echo "$1"
[[ -n "$LOG_FILE" ]] && echo "$1" >> "$LOG_FILE"
}
# 主逻辑
output "===== 内存TOP$TOP_N监控 - $(date) ====="
ps aux | grep -v "^USER" | sort -k6 -rn | head -n "$TOP_N" | \
while read line; do
output "$line"
done
output ""1. 列号问题
ps aux 输出格式:
第4列:%MEM(内存百分比)
第6列:RSS(实际物理内存,单位KB)
排序时要根据需求选择正确的列号!
2. 单位转换
RSS的单位是KB,显示时建议转换为MB:
rss_mb=$(awk "BEGIN {printf \"%.2f\", $rss/1024}")3. 管道中的变量作用域 在管道中使用 while read 循环时,循环内的变量赋值不会影响外部。如需累加统计,应使用进程替换: while read line; do # 处理... done < <(ps aux | grep -v "^USER")
4. 权限问题
普通用户只能看到自己的进程完整信息
需要完整信息请使用 sudo 执行
脚本执行前记得添加执行权限:chmod +x script.sh
5. 性能考虑
避免频繁执行(建议间隔至少5秒)
生产环境建议配合cron定时任务
大量日志写入时考虑日志轮转
1. 基本使用
# 赋予执行权限 chmod +x memory_top10.sh # 执行脚本 ./memory_top10.sh # 或使用sudo查看所有进程 sudo ./memory_top10.sh
2. 高级用法
# 显示TOP20 ./memory_top10_advanced.sh -n 20 # 记录到日志文件 ./memory_top10_advanced.sh -l /var/log/memory_monitor.log # 组合使用 ./memory_top10_advanced.sh -n 15 -l ~/mem.log
3. 定时监控(crontab)
# 编辑定时任务 crontab -e # 每小时执行一次并记录日志 0 * * * * /path/to/memory_top10_advanced.sh -l /var/log/memory_$(date +\%Y\%m\%d).log
扩展练习
当某进程内存使用超过指定阈值时发送邮件通知
同时显示内存和CPU使用TOP10的进程
将监控结果格式化为HTML页面,方便浏览查看
记录多次监控数据,分析内存使用趋势
课程总结
核心知识点 掌握了ps命令的使用和输出格式 学会了管道组合命令进行数据处理 理解了sort排序和head截取的用法 掌握了awk文本处理和格式化输出 学会了脚本参数解析和错误处理
动手实践是最好的学习方式!尝试在自己的Linux系统上运行这些脚本,观察输出结果,并根据实际需求进行改进。