Shell 脚本 / 命令文档
Shell编程实战教学
概述
磁盘使用率监控报警脚本的设计与实现
需求分析
我们需要开发一个监控脚本,实现以下功能:
每分钟检测一次磁盘使用率
当使用率超过 80% 时开始记录
持续超标 5分钟 及以上触发报警
报警方式:记录日志、发送通知
使用率恢复正常后重置计数器
执行流程图
获取当前磁盘使用率(使用 df 命令)
判断使用率是否超过阈值(80%)
如果超过:累加计数器;如果未超过:重置计数器
检查计数器是否达到5(即5分钟)
达到条件则触发报警,记录日志并发送通知
等待60秒后循环执行
1. 获取磁盘使用率
Shell
# 方法一:使用 df 和 awk
usage=$(df -h / | tail -1 | awk '{print $5}' | sed 's/%//')
# 方法二:指定文件系统
usage=$(df -h /dev/sda1 | tail -1 | awk '{print $5}' | tr -d '%')
# 解释:
# df -h / : 查看根分区,-h 表示人类可读格式
# tail -1 : 获取最后一行(数据行)
# awk '{print $5}' : 提取第5列(使用率)
# sed 's/%//' : 去除百分号2. 持久化计数器
由于脚本每次运行都是新进程,我们需要将计数器保存到文件中:
Shell
# 定义计数器文件路径
COUNTER_FILE="/tmp/disk_alert_counter.txt"
# 读取计数器(如果文件不存在则初始化为0)
if [[ -f $COUNTER_FILE ]]; then
counter=$(cat $COUNTER_FILE)
else
counter=0
fi
# 更新计数器
echo $counter > $COUNTER_FILE3. 条件判断与计数逻辑
Shell
# 阈值设定
THRESHOLD=80
ALERT_MINUTES=5
if [[ $usage -gt $THRESHOLD ]]; then
# 超过阈值,计数器加1
counter=$((counter + 1))
echo "警告: 磁盘使用率 ${usage}% 超过阈值,已持续 ${counter} 分钟"
# 检查是否达到报警条件
if [[ $counter -ge $ALERT_MINUTES ]]; then
# 触发报警
send_alert
fi
else
# 使用率正常,重置计数器
counter=0
echo "正常: 磁盘使用率 ${usage}%"
fi完整实现脚本
disk_monitor.sh
#!/bin/bash
#======================================
# 磁盘使用率监控报警脚本
# 作者: Linux专家
# 功能: 监控磁盘使用率,持续超标5分钟后报警
#======================================
# 配置参数
THRESHOLD=80 # 使用率阈值(百分比)
ALERT_MINUTES=5 # 持续超标分钟数
CHECK_PARTITION="/" # 要监控的分区
COUNTER_FILE="/tmp/disk_alert_counter.txt"
LOG_FILE="/var/log/disk_monitor.log"
ALERT_FLAG_FILE="/tmp/disk_alert_sent.flag"
# 日志函数
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}
# 发送报警函数
send_alert() {
local usage=$1
local message="【紧急报警】磁盘使用率已达 ${usage}%,持续超过 ${ALERT_MINUTES} 分钟!"
# 检查是否已经发送过报警(避免重复报警)
if [[ -f $ALERT_FLAG_FILE ]]; then
return
fi
log_message "$message"
# 方式1: 发送邮件(需要配置邮件服务)
echo "$message" | mail -s "磁盘使用率报警" admin@example.com
# 方式2: 系统通知
which notify-send &>/dev/null && notify-send "磁盘报警" "$message"
# 方式3: 写入系统日志
logger -t "DiskMonitor" "$message"
# 方式4: 调用webhook(示例)
# curl -X POST "https://your-webhook-url" -d "message=$message"
# 创建报警标志文件
touch $ALERT_FLAG_FILE
}
# 主监控循环
monitor_disk() {
while true; do
# 获取磁盘使用率
usage=$(df -h $CHECK_PARTITION | tail -1 | awk '{print $5}' | sed 's/%//')
# 检查是否成功获取使用率
if [[ -z "$usage" ]] || ! [[ "$usage" =~ ^[0-9]+$ ]]; then
log_message "错误: 无法获取磁盘使用率"
sleep 60
continue
fi
# 读取计数器
if [[ -f $COUNTER_FILE ]]; then
counter=$(cat $COUNTER_FILE)
else
counter=0
fi
# 判断使用率是否超标
if [[ $usage -gt $THRESHOLD ]]; then
counter=$((counter + 1))
log_message "警告: 磁盘使用率 ${usage}% (阈值: ${THRESHOLD}%),已持续 ${counter} 分钟"
# 达到报警条件
if [[ $counter -ge $ALERT_MINUTES ]]; then
send_alert $usage
fi
else
# 使用率正常,重置计数器
if [[ $counter -gt 0 ]]; then
log_message "恢复: 磁盘使用率 ${usage}%,计数器已重置"
fi
counter=0
# 删除报警标志文件
[[ -f $ALERT_FLAG_FILE ]] && rm -f $ALERT_FLAG_FILE
fi
# 保存计数器
echo $counter > $COUNTER_FILE
# 等待60秒
sleep 60
done
}
# 脚本入口
main() {
log_message "磁盘监控脚本启动,监控分区: $CHECK_PARTITION"
monitor_disk
}
# 执行主函数
main1. 脚本部署
Bash
# 创建脚本文件
sudo vim /usr/local/bin/disk_monitor.sh
# 添加执行权限
sudo chmod +x /usr/local/bin/disk_monitor.sh
# 创建日志目录(如果不存在)
sudo touch /var/log/disk_monitor.log
sudo chmod 644 /var/log/disk_monitor.log2. 配置开机自启动(systemd方式)
Service配置
# 创建 systemd 服务文件
sudo vim /etc/systemd/system/disk-monitor.service
# 添加以下内容:
[Unit]
Description=Disk Usage Monitor Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/disk_monitor.sh
Restart=always
RestartSec=10
User=root
[Install]
WantedBy=multi-user.targetBash
# 重载 systemd 配置
sudo systemctl daemon-reload
# 启动服务
sudo systemctl start disk-monitor
# 设置开机自启
sudo systemctl enable disk-monitor
# 查看服务状态
sudo systemctl status disk-monitor3. 使用crontab方式(替代方案)
Crontab
# 编辑 crontab
crontab -e
# 添加每分钟执行一次(将脚本改为单次检查模式)
* * * * * /usr/local/bin/disk_monitor_once.sh重要注意事项
权限问题:确保脚本有写入日志文件和临时文件的权限。建议使用 root 用户运行或配置适当的权限。
防止重复报警:脚本使用了报警标志文件(ALERT_FLAG_FILE)来防止重复发送报警。只有当使用率恢复正常后,标志文件才会被删除。
分区选择:可以通过修改 CHECK_PARTITION 变量来监控不同的分区,如 "/home"、"/var" 等。
邮件配置:要使用邮件报警功能,需要先配置系统的邮件服务(如 postfix、sendmail)。
资源消耗:虽然每分钟检查一次不会造成太大负担,但在生产环境中建议监控脚本本身的资源使用情况。
测试与验证
测试步骤:
测试命令
# 1. 前台运行脚本观察输出
bash /usr/local/bin/disk_monitor.sh
# 2. 模拟高使用率(创建大文件)
dd if=/dev/zero of=/tmp/testfile bs=1M count=1000
# 3. 查看日志
tail -f /var/log/disk_monitor.log
# 4. 查看计数器文件
cat /tmp/disk_alert_counter.txt
# 5. 测试完成后清理
rm -f /tmp/testfile调试技巧:
使用 set -x 开启调试模式,查看每一步执行
临时降低阈值(如改为20%)方便测试
缩短报警时间(如改为2分钟)加快测试速度
使用 echo 替代实际报警操作进行测试
1. 多分区监控
可以扩展脚本同时监控多个分区:
Shell
PARTITIONS=("/" "/home" "/var")
for partition in "${PARTITIONS[@]}"; do
# 对每个分区分别检查
done2. 集成监控系统
可以将报警信息发送到专业监控系统:
Prometheus + Alertmanager
Zabbix
Nagios
钉钉、企业微信机器人
3. 智能阈值
根据历史数据动态调整阈值,避免误报: