磁盘空间监控与自动清理脚本

代码脚本 · maintenance

监控磁盘空间使用率,超过阈值自动清理临时文件、缓存、日志,查找大文件,发送告警

详细内容

#!/bin/bash # ========================================== # 磁盘空间监控与自动清理脚本 # 用途:监控磁盘空间,超过阈值自动清理,查找大文件 # 使用方法:bash disk_monitor.sh # 定时任务:0 */6 * * * /path/to/disk_monitor.sh # ========================================== # 配置 DISK_THRESHOLD="${DISK_THRESHOLD:-85}" CLEAN_THRESHOLD="${CLEAN_THRESHOLD:-90}" MONITOR_PATHS="${MONITOR_PATHS:-/ /tmp /var /opt}" CLEAN_PATHS="${CLEAN_PATHS:-/tmp /var/tmp /var/log}" LARGE_FILE_SIZE="${LARGE_FILE_SIZE:-100M}" ALERT_EMAIL="${ALERT_EMAIL:-}" ALERT_WEBHOOK="${ALERT_WEBHOOK:-}" DRY_RUN="${DRY_RUN:-false}" echo "========== 磁盘空间监控开始 ==========" echo "监控时间: $(date '+%Y-%m-%d %H:%M:%S')" echo "告警阈值: ${DISK_THRESHOLD}%" echo "清理阈值: ${CLEAN_THRESHOLD}%" echo "试运行: $DRY_RUN" echo "" ALERTS=() FREED_SPACE=0 CLEANED_FILES=0 # 发送告警 send_alert() { local msg=$1 if [ -n "$ALERT_EMAIL" ]; then echo "$msg" | mail -s "磁盘空间告警 - $(hostname)" "$ALERT_EMAIL" 2>/dev/null fi if [ -n "$ALERT_WEBHOOK" ]; then curl -s -X POST "$ALERT_WEBHOOK" -H "Content-Type: application/json" -d "{"content": "$msg"}" >/dev/null 2>&1 fi } # 1. 磁盘空间检查 echo "【1. 磁盘空间检查】" df -h | grep -E '^/dev/' | while read line; do filesystem=$(echo $line | awk '{print $1}') size=$(echo $line | awk '{print $2}') used=$(echo $line | awk '{print $3}') avail=$(echo $line | awk '{print $4}') usage=$(echo $line | awk '{print $5}' | tr -d '%') mount=$(echo $line | awk '{print $6}') if [ "$usage" -ge "$DISK_THRESHOLD" ]; then echo " 🔴 $mount ($filesystem): ${usage}% (已用$used/总$size,可用$avail)" ALERTS+=("🔴 $mount 使用率 ${usage}%,超过阈值 ${DISK_THRESHOLD}%") else echo " ✅ $mount ($filesystem): ${usage}% (已用$used/总$size,可用$avail)" fi done echo "" # 2. 大文件查找 echo "【2. 大文件查找 (> $LARGE_FILE_SIZE)】" for path in $MONITOR_PATHS; do if [ -d "$path" ]; then echo " 目录: $path" find "$path" -xdev -type f -size +"$LARGE_FILE_SIZE" -exec du -h {} \; 2>/dev/null | sort -rh | head -10 | while read size file; do echo " $size - $file" done fi done echo "" # 3. 自动清理 echo "【3. 自动清理】" NEED_CLEAN=false # 检查是否需要清理 for path in $MONITOR_PATHS; do if [ -d "$path" ]; then usage=$(df "$path" | tail -1 | awk '{print $5}' | tr -d '%') if [ "$usage" -ge "$CLEAN_THRESHOLD" ]; then NEED_CLEAN=true break fi fi done if [ "$NEED_CLEAN" = "true" ]; then echo " 磁盘空间超过清理阈值,开始清理..." # 清理临时文件 for path in $CLEAN_PATHS; do if [ -d "$path" ]; then echo " 清理: $path" # 删除超过7天的临时文件 files=$(find "$path" -xdev -type f -atime +7 2>/dev/null) if [ -n "$files" ]; then count=$(echo "$files" | wc -l) size=$(echo "$files" | xargs du -ch 2>/dev/null | tail -1 | cut -f1) if [ "$DRY_RUN" = "true" ]; then echo " [试运行] 将删除 $count 个文件,释放 $size" else echo "$files" | xargs rm -f 2>/dev/null echo " 已删除 $count 个文件,释放 $size" fi CLEANED_FILES=$((CLEANED_FILES + count)) fi fi done # 清理包管理器缓存 if command -v apt-get &> /dev/null; then echo " 清理APT缓存..." if [ "$DRY_RUN" = "true" ]; then echo " [试运行] apt-get clean" else apt-get clean 2>/dev/null echo " APT缓存已清理" fi fi if command -v yum &> /dev/null; then echo " 清理YUM缓存..." if [ "$DRY_RUN" = "true" ]; then echo " [试运行] yum clean all" else yum clean all 2>/dev/null echo " YUM缓存已清理" fi fi # 清理Docker if command -v docker &> /dev/null && docker info &>/dev/null; then echo " 清理Docker无用资源..." if [ "$DRY_RUN" = "true" ]; then echo " [试运行] docker system prune -f" else docker system prune -f 2>/dev/null echo " Docker无用资源已清理" fi fi # 清理journal日志 if command -v journalctl &> /dev/null; then echo " 清理journal日志(保留最近7天)..." if [ "$DRY_RUN" = "true" ]; then echo " [试运行] journalctl --vacuum-time=7d" else journalctl --vacuum-time=7d 2>/dev/null echo " journal日志已清理" fi fi else echo " 磁盘空间未超过清理阈值,跳过清理" fi echo "" # 4. inode使用情况 echo "【4. Inode使用情况】" df -i | grep -E '^/dev/' | while read line; do filesystem=$(echo $line | awk '{print $1}') iused=$(echo $line | awk '{print $3}') ifree=$(echo $line | awk '{print $4}') iusage=$(echo $line | awk '{print $5}' | tr -d '%') mount=$(echo $line | awk '{print $6}') if [ "$iusage" -ge 80 ]; then echo " 🔴 $mount: Inode使用率 ${iusage}% (已用$iused,可用$ifree)" ALERTS+=("🔴 $mount Inode使用率 ${iusage}%") else echo " ✅ $mount: Inode使用率 ${iusage}%" fi done echo "" # 5. 目录大小统计 echo "【5. 大目录统计 (Top 10)】" for path in $MONITOR_PATHS; do if [ -d "$path" ]; then echo " $path:" du -h --max-depth=1 "$path" 2>/dev/null | sort -rh | head -10 | while read size dir; do echo " $size - $dir" done fi done echo "" # 6. 告警汇总 echo "【6. 告警汇总】" if [ ${#ALERTS[@]} -gt 0 ]; then echo " 🔴 发现 ${#ALERTS[@]} 个告警:" for alert in "${ALERTS[@]}"; do echo " $alert" done # 发送告警 msg="磁盘空间告警 - $(hostname) " for alert in "${ALERTS[@]}"; do msg="$msg$alert " done send_alert "$msg" else echo " ✅ 磁盘空间正常,无告警" fi echo "" # 清理汇总 echo "【清理汇总】" echo " 清理文件数: $CLEANED_FILES" echo " 试运行: $DRY_RUN" echo "" echo "========== 监控完成 ==========" echo "提示: 可将此脚本加入crontab定时执行,例如每6小时执行一次" echo " 0 */6 * * * /path/to/disk_monitor.sh"

适配环境

适配系统:CentOS 7+,Ubuntu 18.04+,Debian 10+

依赖环境:bash 4.0+

参数说明

[{"name": "DISK_THRESHOLD", "label": "\u544a\u8b66\u9608\u503c(%)", "default": "85"}, {"name": "CLEAN_THRESHOLD", "label": "\u6e05\u7406\u9608\u503c(%)", "default": "90"}, {"name": "MONITOR_PATHS", "label": "\u76d1\u63a7\u8def\u5f84(\u7a7a\u683c\u5206\u9694)", "default": "/ /tmp /var"}, {"name": "LARGE_FILE_SIZE", "label": "\u5927\u6587\u4ef6\u9608\u503c", "default": "100M"}, {"name": "DRY_RUN", "label": "\u8bd5\u8fd0\u884c(true/false)", "default": "false"}]
磁盘监控空间清理大文件查找告警

更多maintenance