题目
设计一个监控进程资源使用率的Shell脚本
信息
- 类型:问答
- 难度:⭐⭐
考点
进程监控,资源阈值判断,邮件告警,脚本健壮性
快速回答
实现一个监控指定进程CPU/内存使用率的Shell脚本,需包含:
- 使用
ps命令获取进程资源数据 - 设置CPU和内存的双重阈值(如CPU>80%且内存>70%)
- 超过阈值时发送邮件告警(使用
mail命令) - 包含参数校验、错误处理和防重复告警机制
核心原理
通过ps -p PID -o %cpu,%mem获取进程资源数据,利用数值比较判断阈值,结合mail命令实现告警。关键点包括:
- 使用浮点数比较(通过
bc工具) - 设置状态文件防止重复告警
- 捕获进程不存在等异常情况
代码示例
#!/bin/bash
# 配置参数
PID="$1"
CPU_THRESHOLD=80.0
MEM_THRESHOLD=70.0
EMAIL="admin@example.com"
STATUS_FILE="/tmp/process_monitor.status"
# 参数校验
if [ -z "$PID" ] || ! ps -p "$PID" &>/dev/null; then
echo "错误:无效的进程ID或进程不存在"
exit 1
fi
# 获取资源使用率
read -r CPU_USAGE MEM_USAGE <<< $(ps -p "$PID" -o %cpu=,%mem=)
# 浮点数比较函数
compare_floats() {
echo "$1 > $2" | bc -l
}
# 阈值判断
CPU_OVER=$(compare_floats "$CPU_USAGE" "$CPU_THRESHOLD")
MEM_OVER=$(compare_floats "$MEM_USAGE" "$MEM_THRESHOLD")
if [ "$CPU_OVER" -eq 1 ] && [ "$MEM_OVER" -eq 1 ]; then
# 检查是否已发送告警
if [ ! -f "$STATUS_FILE" ] || [ "$(cat "$STATUS_FILE")" != "ALERT_SENT" ]; then
echo "进程 $PID 资源超标:CPU=${CPU_USAGE}% 内存=${MEM_USAGE}%" | \
mail -s "[紧急告警] 进程 $PID 资源异常" "$EMAIL"
echo "ALERT_SENT" > "$STATUS_FILE"
fi
else
# 恢复时清除状态
[ -f "$STATUS_FILE" ] && rm -f "$STATUS_FILE"
fi最佳实践
- 状态文件机制:使用临时文件记录告警状态,避免邮件轰炸
- 参数化配置:阈值、邮件地址等设为变量,便于维护
- 错误处理:检查进程是否存在,验证
mail命令可用性 - 日志记录:添加
logger命令将事件写入系统日志
常见错误
- 整数比较:直接使用
-gt比较浮点数会导致语法错误 - 僵尸进程:监控僵尸进程时资源数据可能为0,需特殊处理
- 邮件配置:未配置SMTP导致
mail命令失效 - 权限问题:状态文件路径不可写导致脚本异常
扩展知识
- 定时任务:通过
crontab -e添加*/5 * * * * /path/to/script.sh PID实现每5分钟监控 - 进程选择:支持进程名监控(
pgrep -f process_name) - 高级告警:集成Telegram/钉钉API实现多通道告警
- 替代方案:使用
top -b -n1 -p PID获取实时数据