这个脚本解决什么问题?

磁盘和内存的问题往往是“温水煮青蛙”:今天 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、任何你能想到的指标。