你被手机告警惊醒 —— 业务突然卡顿,用户投诉不断。
登录服务器后,你手忙脚乱排查:top 命令一看 CPU 使用率 100%,df 命令发现磁盘满到无法写入,内存也快耗尽……
折腾了 1 小时才解决,你是否会想:要是有个简单的监控脚本,能提前告警,何必要熬夜排错?
很多新手运维都有个误区:觉得系统监控必须搭建 zabbix、prometheus 这类复杂工具,门槛高、配置繁琐,小服务器根本用不上。
其实不然 ——一个简单的 Shell 脚本,就能搞定 CPU、内存、磁盘使用率的实时监控和告警,无需复杂部署,新手也能 10 分钟上手,完美解决 Linux 服务器基础监控需求,轻松实现 CPU 使用率告警、磁盘满告警。
本文将从 “核心命令→踩坑修复→脚本编写→告警配置→定时任务”,一步步教你编写属于自己的 Linux 监控脚本。
一、为什么需要这个监控脚本?
对于个人服务器、小型业务服务器,复杂监控系统的 “性价比太低”:
- 部署复杂:zabbix 等工具需要安装服务端、客户端,配置流程繁琐,新手容易踩坑;
- 资源占用:监控服务本身会消耗 CPU、内存,对于配置较低的服务器,反而增加负担;
- 需求冗余:大多数小型服务器,只需要监控 CPU、内存、磁盘这 3 个核心指标,无需复杂的指标收集。
而我们编写的这个脚本,具备 3 个核心优势:
- 极简无依赖:基于 Linux 自带命令编写,无需安装任何额外软件,复制就能执行;
- 灵活可定制:阈值(告警临界值)可自由修改,适配不同服务器需求;
- 多渠道告警:支持邮件、企业微信告警,异常情况及时通知,不用实时盯服务器;
- 踩坑全修复:解决了不同系统 CPU 命令兼容问题、企业微信告警报错等高频问题。
一句话总结:花 10 分钟配置,换长期省心,再也不用手动排查 CPU、磁盘异常。
二、核心命令详解:获取 CPU、内存、磁盘使用率
脚本的核心,是通过 Linux 自带命令,精准获取 CPU、内存、磁盘的使用率,这是监控和告警的基础。每个命令都附带详细解读 + 踩坑修复,新手也能看懂原理,避免 “复制即用却不懂含义”。
2.1 获取 CPU 使用率
新手最常踩的坑:不同 Linux 发行版的top命令输出格式不同,导致命令执行后终端无任何输出。
这里给你 2 套方案,优先推荐全系统通用方案,彻底解决兼容问题。
方案 1:
# 获取CPU使用率(排除空闲进程,计算非空闲使用率)
cpu_usage=$(top -bn1 | grep '%Cpu' | sed 's/.*, *\([0-9.]*\)%* id.*/\1/' | awk '{print 100 - $1}' | awk -F. '{print $1"."$2}' | cut -c1-4)
echo"CPU使用率:$cpu_usage%"
方案 2:全系统通用 CPU 命令(推荐,无兼容问题)
基于内核 /proc/stat文件获取 CPU 统计信息,所有 Linux 系统通用,格式固定,不会因为 top版本差异出问题,结果更准确:
# 全系统通用:获取CPU使用率(采样1秒,结果更精准)
# 第一步:获取第一次CPU统计
cpu1=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
sleep 1
# 第二步:获取第二次CPU统计
cpu2=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
# 第三步:计算两次采样的差值,得出CPU使用率(保留1位小数)
cpu_usage=$(echo"$cpu1$cpu2" | awk '{
idle1 = $4; total1 = $1+$2+$3+$4+$5+$6+$7;
idle2 = $11; total2 = $8+$9+$10+$11+$12+$13+$14;
idle = idle2 - idle1; total = total2 - total1;
usage = 100 - (idle / total * 100);
printf "%.1f", usage;
}')
# 输出结果
echo"CPU使用率:$cpu_usage%"
命令解读(新手可跳过,不影响使用)
/proc/stat:内核直接提供的 CPU 统计文件,格式固定,所有 Linux 系统通用;- 两次采样间隔 1 秒:计算的是 1 秒内的平均 CPU 使用率,比
top -bn1单次采样更精准; awk计算:通过两次采样的空闲时间、总时间差值,算出真实使用率,避免 top格式兼容问题;printf "%.1f"
2.2 获取内存使用率(核心命令)
常用命令(精准计算内存使用率,排除缓存 / 缓冲,贴合实际使用场景,避免误告警):
# 获取内存总大小、已用大小(排除缓存、缓冲,计算真实使用率)
mem_total=$(free -m | grep Mem | awk '{print $2}')
mem_used=$(free -m | grep Mem | awk '{print $3 - $6 - $7}')
mem_usage=$(echo"scale=1; $mem_used / $mem_total * 100" | bc | cut -c1-4)
# 输出结果
echo"内存使用率:$mem_usage%"
命令解读
free -mmem_totalmem_used:实际已用内存(减去缓存、缓冲,避免 “缓存占用高就触发告警” 的误判);bc:用于小数计算(Linux 默认不支持小数计算,需用 bc 工具,大多数系统自带)。
执行后效果:输出内存使用率,如 78.5(代表 78.5%)。
2.3 获取磁盘使用率(核心命令)
常用命令(监控根目录 /,可修改为其他目录,如 /data):
# 获取根目录/的磁盘使用率(可修改目录,如/dev/sda1对应的数据盘)
disk_usage=$(df -h | grep '/$' | awk '{print $5}' | sed 's/%//')
# 输出结果
echo"磁盘使用率:$disk_usage%"
命令解读
df -h:以人类可读的格式(如 GB、MB)显示磁盘使用情况;grep '/$':筛选根目录 /的磁盘信息(若需监控其他目录,可改为 grep '/data');sed 's/%//':去掉使用率后的 % 符号,方便后续数值比较(如 90,代表 90%)。
执行后效果:输出磁盘使用率,如 88(代表 88%)。
监控脚本核心 3 步口诀(好记好传播): 命令获取值,阈值做判断,告警送通知,定时保安全。
一句话记住:用自带命令拿指标,设好阈值判异常,触发后发告警,定时执行不中断。
三、实战:编写完整监控脚本
结合上面的核心命令,编写完整的监控脚本,包含 “指标获取→阈值判断→告警逻辑”、企业微信告警报错问题,新手可直接复制到服务器,修改阈值和告警配置即可使用。
3.1 脚本完整代码(命名为 monitor.sh)
#!/bin/bash
# Linux系统监控脚本:CPU+内存+磁盘使用率告警
# 作者:零距技术仓
# 核心功能:监控CPU、内存、磁盘使用率,超过阈值触发邮件/企业微信告警
# CPU命令全系统兼容、企业微信93000报错说明、小数计算异常
# 可直接复制执行,修改下方阈值和告警配置即可
##############################################################################
# 第一步:设置监控阈值(可根据自己服务器配置修改,新手推荐默认值)
##############################################################################
CPU_THRESHOLD=80 # CPU使用率阈值,超过此值告警(默认80%)
MEM_THRESHOLD=85 # 内存使用率阈值,超过此值告警(默认85%)
DISK_THRESHOLD=90 # 磁盘使用率阈值,超过此值告警(默认90%)
##############################################################################
# 第二步:获取当前CPU、内存、磁盘使用率(复用上面的核心命令)
##############################################################################
# 获取CPU使用率(全系统通用版,无兼容问题,推荐)
cpu1=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
sleep 1
cpu2=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
cpu_usage=$(echo"$cpu1$cpu2" | awk '{
idle1 = $4; total1 = $1+$2+$3+$4+$5+$6+$7;
idle2 = $11; total2 = $8+$9+$10+$11+$12+$13+$14;
idle = idle2 - idle1; total = total2 - total1;
usage = 100 - (idle / total * 100);
printf "%.1f", usage;
}')
# 【备用】
cpu_usage=$(top -bn1 | grep '%Cpu' | sed 's/.*, *\([0-9.]*\)%* id.*/\1/' | awk '{print 100 - $1}' | awk -F. '{print $1"."$2}' | cut -c1-4)
# 获取内存使用率(保留1位小数,排除缓存)
mem_total=$(free -m | grep Mem | awk '{print $2}')
mem_used=$(free -m | grep Mem | awk '{print $3 - $6 - $7}')
mem_usage=$(echo"scale=1; $mem_used / $mem_total * 100" | bc | cut -c1-4)
# 获取根目录磁盘使用率(无小数,去掉%符号)
disk_usage=$(df -h | grep '/$' | awk '{print $5}' | sed 's/%//')
# 获取当前时间、服务器IP(用于告警信息)
current_time=$(date "+%Y-%m-%d %H:%M:%S")
server_ip=$(hostname -I | awk '{print $1}')
##############################################################################
# 第三步:告警信息编写(可自定义,清晰易懂即可)
##############################################################################
# 基础告警信息
alarm_info="【Linux服务器监控告警】
告警时间:$current_time
服务器IP:$server_ip
告警类型:系统资源使用率异常
--------------------------
CPU使用率:$cpu_usage% (阈值:$CPU_THRESHOLD%)
内存使用率:$mem_usage% (阈值:$MEM_THRESHOLD%)
磁盘使用率:$disk_usage% (阈值:$DISK_THRESHOLD%)
--------------------------
请及时登录服务器排查,避免影响业务正常运行!"
##############################################################################
# 第四步:阈值判断与告警触发(核心逻辑)
##############################################################################
# 定义告警标记(0=无告警,1=有告警)
alarm_flag=0
# 1. CPU使用率判断(兼容小数比较)
if (( $(echo"$cpu_usage > $CPU_THRESHOLD" | bc -l) )); then
echo"[$current_time] CPU使用率异常:$cpu_usage%,触发告警!"
alarm_flag=1
fi
# 2. 内存使用率判断(兼容小数比较)
if (( $(echo"$mem_usage > $MEM_THRESHOLD" | bc -l) )); then
echo"[$current_time] 内存使用率异常:$mem_usage%,触发告警!"
alarm_flag=1
fi
# 3. 磁盘使用率判断(整数比较)
if [ $disk_usage -gt $DISK_THRESHOLD ]; then
echo"[$current_time] 磁盘使用率异常:$disk_usage%,触发告警!"
alarm_flag=1
fi
##############################################################################
# 第五步:告警通知(邮件/企业微信,二选一或同时启用,按需配置)
##############################################################################
# --------------------------
# 选项1:邮件告警(需配置服务器邮件发送功能)
# --------------------------
# 收件人邮箱(修改为自己的邮箱)
email_recipient="your_email@163.com"
# 邮件标题
email_subject="【Linux告警】服务器$server_ip 资源使用率异常"
# 触发告警时发送邮件
if [ $alarm_flag -eq 1 ]; then
echo"$alarm_info" | mail -s "$email_subject"$email_recipient
fi
# --------------------------
# 选项2:企业微信告警(推荐,实时推送,无需配置邮件)
# 常见报错:errcode:93000 解决方法见下文告警配置章节
# --------------------------
# 企业微信机器人webhook地址(修改为自己的机器人完整地址,不要只填key)
wechat_webhook="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=your_webhook_key"
# 企业微信告警消息格式(适配机器人推送,修复换行问题)
wechat_msg='{
"msgtype": "text",
"text": {
"content": "'"$alarm_info"'"
}
}'
# 触发告警时推送企业微信消息(静默执行,不输出错误)
if [ $alarm_flag -eq 1 ]; then
curl -s -H "Content-Type: application/json" -X POST -d "$wechat_msg""$wechat_webhook" > /dev/null 2>&1
fi
##############################################################################
# 第六步:脚本日志(可选,记录监控历史,便于排查)
##############################################################################
# 日志保存路径(可修改,确保目录存在)
log_path="/var/log/linux_monitor.log"
# 自动创建日志文件(避免目录不存在报错)
mkdir -p $(dirname $log_path)
touch $log_path
# 写入日志(格式:时间 服务器IP CPU 内存 磁盘 告警状态)
echo"[$current_time] 服务器IP:$server_ip | CPU:$cpu_usage% | 内存:$mem_usage% | 磁盘:$disk_usage% | 告警状态:$([ $alarm_flag -eq 1 ] && echo "异常" || echo "正常")" >> $log_path
3.2 脚本使用步骤(新手必看,一步都不能少)
创建脚本文件(用 vi 编辑器,简单易操作):
vi /root/monitor.sh
复制上面的完整代码,粘贴到 vi 编辑器中(按 i进入编辑模式,粘贴后按 Esc,输入 :wq保存退出);
修改脚本中的关键配置(必做,否则告警无法生效):
- 邮件告警:修改
email_recipient为自己的邮箱(如 123456@163.com); - 企业微信告警:修改
wechat_webhook为自己的企业微信机器人完整 webhook 地址(不要只填 key,完整复制)。
- 阈值配置:根据自己服务器配置修改
CPU_THRESHOLD、MEM_THRESHOLD、DISK_THRESHOLD(新手推荐默认值); - 日志路径:默认
/var/log/linux_monitor.log,无需修改,脚本会自动创建日志文件。
给脚本添加执行权限(必须做,否则无法执行):
chmod +x /root/monitor.sh
测试脚本(验证是否能正常执行,无报错):
/root/monitor.sh
执行后无报错,且日志文件 /var/log/linux_monitor.log中有记录,说明脚本正常。
四、告警配置详解(含报错修复,新手推荐企业微信)
脚本中提供了两种告警方式,新手推荐企业微信(配置简单、实时推送),邮件告警需要配置服务器邮件发送功能,稍复杂,下面分别讲解配置方法 + 踩坑修复。
4.1 企业微信告警配置(推荐,5 分钟搞定,含 93000 报错修复)
核心是获取企业微信机器人的完整 webhook 地址,步骤如下:
- 点击群聊右上角「...」→「群机器人」→「添加机器人」;
- 给机器人命名(如 “Linux 监控告警”),点击「添加」,完整复制生成的 webhook 地址(格式:
https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxx); - 将复制的完整 webhook 地址,替换脚本中
wechat_webhook的值(完整替换,不要只填 key,不要遗漏任何字符); - 测试:手动修改脚本中的阈值(比如将 CPU 阈值改为 10%),执行脚本,若群聊收到告警消息,说明配置成功。
【高频报错修复】errcode:93000 invalid webhook url
你遇到的这个报错,99% 的原因是以下 3 种,按顺序排查即可解决:
- webhook 地址不完整:只填了 key,没有填完整的地址,必须完整复制机器人生成的
https://qyapi.weixin.qq.com/...完整链接; - webhook 地址写错 / 复制不全:复制时遗漏了字符,或 key 写错,重新进入机器人页面,完整复制 webhook 地址;
- 机器人被删除 / 禁用:进入群聊机器人页面,检查机器人是否正常,若被删除,重新创建机器人即可;
- 服务器无法访问企业微信接口:测试服务器是否能访问公网,执行
curl https://qyapi.weixin.qq.com,若无法访问,检查服务器防火墙 / 网络配置。
注意:企业微信机器人 webhook 地址不要泄露,否则可能被恶意利用,导致群聊收到垃圾消息。
4.2 邮件告警配置(适合习惯用邮件的用户)
需要先在服务器上安装邮件发送工具(sendmail 或 postfix),以 CentOS 为例,步骤如下:
- 安装 sendmail(CentOS 默认自带,若没有则安装):
yum install -y sendmail
- 启动 sendmail 服务,并设置开机自启:
systemctl start sendmail
systemctl enable sendmail
- 测试邮件发送(替换为自己的邮箱):
echo"测试邮件" | mail -s "Linux监控测试" your_email@163.com
- 若能收到测试邮件,说明邮件配置成功,再执行监控脚本即可触发邮件告警。
注意:Ubuntu 系统安装命令为 apt install -y sendmail,其他系统可对应调整;若收不到邮件,检查邮箱垃圾箱,或配置 SMTP 授权码(163/QQ 邮箱需要)。
五、配置定时任务:让脚本自动执行(核心步骤)
脚本编写完成后,需要配置 Linux 定时任务(crontab),让脚本每分钟 / 每 5 分钟自动执行,实现 “实时监控、自动告警”,无需手动执行。
5.1 配置定时任务步骤
- 编辑 crontab 配置文件:
crontab -e
- 在文件末尾添加定时任务(二选一,推荐每 5 分钟执行一次,减轻服务器压力):
- 每 5 分钟执行一次(推荐,个人 / 小型服务器足够):
*/5 * * * * /root/monitor.sh
- 每分钟执行一次(适合对监控实时性要求高的场景):
* * * * * /root/monitor.sh
- 重启 crontab 服务,确保定时任务生效:
# CentOS系统
systemctl restart crond
systemctl enable crond
# Ubuntu系统
systemctl restart cron
systemctl enable cron
5.2 定时任务解读(新手必懂)
crontab 定时任务的格式为:分 时 日 月 周 命令
*/5 * * * *:代表每 5 分钟执行一次(*/n表示每 n 个单位);* * * * */root/monitor.sh:脚本的绝对路径,必须写绝对路径,否则定时任务可能执行失败。
5.3 验证定时任务是否生效
等待 5 分钟(或 1 分钟)后,查看日志文件,若有新的监控记录,说明定时任务正常:
cat /var/log/linux_monitor.log
若日志中有最新的时间记录,且告警状态正常,说明定时任务配置成功。
六、常见问题与避坑指南
很多新手配置完脚本后,会遇到 “脚本不执行”“告警收不到”“CPU 命令无输出” 等问题,这里总结 6 个最常见的坑,以及对应的解决方法,帮你少走弯路。
生产环境 3 个必踩坑(重点记):
- 脚本无执行权限:忘记给脚本加
chmod +x,导致定时任务执行失败; - 定时任务写相对路径:脚本路径写
monitor.sh,而非绝对路径 /root/monitor.sh; - 告警配置错误:企业微信 webhook 写错、邮件收件人写错,导致告警收不到。
记住一句话:脚本要有权限,路径要写绝对,告警配置要核对。
问题 1:CPU 命令执行后,终端无任何输出
- 原因:
top命令输出格式与 grep关键词不匹配(比如你的系统是 xCpu,命令采用了 Cpu(s)); - 优先使用本文提供的 /proc/stat 通用版 CPU 命令 ,彻底解决兼容问题;
- 若要用
top命令,先执行 top -n1 | head -10,查看 CPU 行的标识(如 xCpu、%Cpu),修改 grep后的关键词即可。
问题 2:脚本执行报错 “bc: command not found”
- 解决:安装 bc 工具:
# CentOS
yum install -y bc
# Ubuntu
apt install -y bc
问题 3:定时任务不执行,日志无记录
- 原因 1:脚本无执行权限,解决:
chmod +x /root/monitor.sh; - 原因 2:脚本路径写相对路径,解决:将 crontab 中的命令改为绝对路径
/root/monitor.sh; - 原因 3:crontab 服务未启动,解决:重启 crontab 服务(见上文步骤)。
问题 4:企业微信告警报错 errcode:93000
- 原因 & 解决:见本文 4.1 节的【高频报错修复】,99% 是 webhook 地址不完整 / 错误,重新复制完整地址即可解决。
问题 5:磁盘使用率计算错误,显示异常
- 原因:脚本中监控的是根目录
/,若需要监控其他磁盘(如 /data),需修改磁盘命令; - 解决:将磁盘命令改为(替换
/data为自己需要监控的目录):disk_usage=$(df -h | grep '/data' | awk '{print $5}' | sed 's/%//')
问题 6:脚本执行后,企业微信收不到告警
七、实用技巧与进阶优化
结合实战经验,补充几个实用技巧,让监控脚本更完善、更省心,适配更多场景。
- 自定义告警信息:可在
alarm_info中添加更多内容,如服务器主机名、异常进程信息(可添加 ps aux --sort=-%cpu | head -5获取 CPU 占用最高的 5 个进程); - 调整阈值:根据服务器配置调整,比如低配服务器(1 核 2G),可将内存阈值改为 80%,避免误告警;
- 日志清理:脚本日志会不断增长,可结合 logrotate 工具,配置日志轮转,避免日志占满磁盘;
- 多目录监控:若需要监控多个磁盘目录(如
/、/data),可复制磁盘使用率的命令,修改目录后添加判断逻辑; - 异常恢复通知:可在脚本中添加 “告警恢复” 逻辑,当资源使用率低于阈值时,发送恢复通知,避免一直担心;
- 钉钉 / 飞书告警:只需修改企业微信告警部分的 curl 请求格式,即可适配钉钉、飞书机器人,实现多平台告警。
如果你觉得本文对你有帮助,欢迎点赞、推荐、转发,关注我,后续会分享更多Linux入门干货!
文 / 零距技术仓
记录每一次真实的折腾 (#^.^#)
🚀 想看到更多实用折腾技巧?
👉 先关注
💬 评论区说说你的经历或想看的内容
👍 点赞表示支持
🔁 顺手分享给也在折腾的人,让大家都少踩坑 😎