这个脚本解决什么问题?
磁盘和内存的问题往往是“温水煮青蛙”:今天 60%,过几天 75%,等某天早上发现已经 95% 了。这时候才去处理,可能已经晚了——服务崩了、数据写不进了。
正确的做法是设一个阈值,让脚本每天盯梢:一旦使用率超过 80%,就报警,把”事故”提前变成”预警”,在出问题之前就处理掉。
脚本全文
用途: 实时读取根分区磁盘使用率和内存使用率,超过阈值就写入告警日志,可扩展接入钉钉/企微/邮件通知。
#!/bin/bash
THRESHOLD=80 # 阈值:使用率超过 80% 就告警
USED=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
MEM_USED=$(free | awk '/Mem:/ {printf "%.0f", $3/$2*100}')
if [ "$USED" -gt "$THRESHOLD" ]; then
echo "[告警] 根分区使用率已达 ${USED}%" >> /var/log/monitor.log
# 在这里接通知:curl 钉钉/企微 webhook、或 sendmail 发邮件
fi
if [ "$MEM_USED" -gt "$THRESHOLD" ]; then
echo "[告警] 内存使用率已达 ${MEM_USED}%" >> /var/log/monitor.log
fi
一行行看懂它(重点是那两行取值命令)
取磁盘使用率这行,拆开看其实是”命令输出 → 提取 → 清洗”三小步:
df -h /:显示根分区/的使用情况,输出里第二行第二列附近就有使用%。| awk 'NR==2 {print $5}':awk按行处理,NR==2表示取第二行(根分区那行),$5表示打印这一行的第 5 列(就是使用率那列,形如80%)。| tr -d '%':tr -d把结果里所有%符号删掉,得到纯数字80,才能和THRESHOLD比大小。
内存那行用了第二种写法:free 输出里 Mem: 那行,$3/$2*100 用已用除以总量得到百分比,printf "%.0f" 四舍五入成整数。
这就是脚本里最高频的套路: 拿任何命令的文本输出,用 awk/grep 挑出关键数字,存进变量做判断。会了这一招,几乎所有”监控”类脚本都能写了。
怎么用,以及如何接真实告警
chmod +x monitor.sh
crontab -e
*/10 * * * * /root/scripts/monitor.sh
# 想把告警发出来?把 if 里那行 echo 换掉或加上,例如钉钉 webhook:
# curl -s "https://oapi.dingtalk.com/robot/send?access_token=你的token" \
# -H 'Content-Type: application/json' \
# -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"磁盘已达 ${USED}%\"}}"
常见坑
| 现象 | 原因 | 解决 |
|---|---|---|
| 只报磁盘不报内存 / 反之 | 判断条件没写完整 | 两条 if 都要有,别漏 |
| 取不到数字导致报错 | awk 没匹配到 | 先手动跑 df -h / \| awk 'NR==2{print $5}' 看输出 |
| 阈值判断总不准 | 百分比带了 % 没法比 | 确认 tr -d '%' 清掉了百分号 |
小结
监控告警脚本的核心是”取数 + 阈值 + 通知“三件事。取数靠 awk 从命令输出里抽数字,阈值靠 if 比较,通知靠 curl 调 webhook。把这三件套组合起来,你就能盯住磁盘、内存、CPU、任何你能想到的指标。