磁盘清理脚本#

脚本说明#

磁盘清理脚本用于自动清理系统中的临时文件、日志文件、缓存文件等,释放磁盘空间。

脚本代码#

#!/bin/bash

# 磁盘清理脚本
# 功能:自动清理系统中的临时文件和缓存
# 作者:System Admin
# 日期:2026-01-01

set -euo pipefail

# 配置变量
LOG_FILE="/var/log/disk_cleanup.log"
DRY_RUN=false
VERBOSE=false
MIN_DISK_SPACE=20  # 最小可用空间(GB)
TEMP_DIRS=("/tmp" "/var/tmp" "/var/cache")
LOG_DIRS=("/var/log")
CACHE_DIRS=("/var/cache/apt/archives" "/var/cache/yum" "~/.cache")

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# 日志函数
log() {
    local level=$1
    shift
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$level] $@" | tee -a "$LOG_FILE"
}

log_info() {
    log "INFO" "$@"
}

log_error() {
    log "ERROR" "$@"
}

log_warning() {
    log "WARNING" "$@"
}

# 获取磁盘使用情况
get_disk_usage() {
    local mount_point=${1:-/}
    df -h "$mount_point" | tail -n 1 | awk '{print $5}' | cut -d'%' -f1
}

# 获取可用磁盘空间(GB)
get_free_space() {
    local mount_point=${1:-/}
    df -BG "$mount_point" | tail -n 1 | awk '{print $4}' | sed 's/G//'
}

# 检查磁盘空间
check_disk_space() {
    local usage=$(get_disk_usage)
    local free=$(get_free_space)
    
    log_info "当前磁盘使用率: ${usage}%, 可用空间: ${free}GB"
    
    if [ $free -lt $MIN_DISK_SPACE ]; then
        log_warning "磁盘空间不足: ${free}GB < ${MIN_DISK_SPACE}GB"
        return 1
    fi
    
    return 0
}

# 清理临时文件
clean_temp_files() {
    log_info "===== 清理临时文件 ====="
    
    local total_size=0
    
    for dir in "${TEMP_DIRS[@]}"; do
        if [ -d "$dir" ]; then
            local size_before=$(du -sm "$dir" | cut -f1)
            
            log_info "清理目录: $dir"
            
            if [ "$DRY_RUN" = true ]; then
                log_info "[DRY RUN] 将清理: $dir"
            else
                # 清理超过7天的文件
                find "$dir" -type f -mtime +7 -delete 2>/dev/null || true
                # 清理空目录
                find "$dir" -type d -empty -delete 2>/dev/null || true
            fi
            
            local size_after=$(du -sm "$dir" | cut -f1)
            local freed=$((size_before - size_after))
            total_size=$((total_size + freed))
            
            log_info "释放空间: ${freed}MB"
        fi
    done
    
    log_info "临时文件清理完成,共释放: ${total_size}MB"
}

# 清理日志文件
clean_log_files() {
    log_info "===== 清理日志文件 ====="
    
    local total_size=0
    
    for dir in "${LOG_DIRS[@]}"; do
        if [ -d "$dir" ]; then
            local size_before=$(du -sm "$dir" | cut -f1)
            
            log_info "清理日志目录: $dir"
            
            if [ "$DRY_RUN" = true ]; then
                log_info "[DRY RUN] 将清理日志文件: $dir"
            else
                # 清理压缩的旧日志
                find "$dir" -name "*.gz" -mtime +30 -delete 2>/dev/null || true
                find "$dir" -name "*.bz2" -mtime +30 -delete 2>/dev/null || true
                find "$dir" -name "*.xz" -mtime +30 -delete 2>/dev/null || true
                
                # 清理大型日志文件(>100MB)
                find "$dir" -type f -size +100M -exec truncate -s 0 {} \; 2>/dev/null || true
            fi
            
            local size_after=$(du -sm "$dir" | cut -f1)
            local freed=$((size_before - size_after))
            total_size=$((total_size + freed))
            
            log_info "释放空间: ${freed}MB"
        fi
    done
    
    log_info "日志文件清理完成,共释放: ${total_size}MB"
}

# 清理缓存文件
clean_cache_files() {
    log_info "===== 清理缓存文件 ====="
    
    local total_size=0
    
    for dir in "${CACHE_DIRS[@]}"; do
        if [ -d "$dir" ]; then
            local size_before=$(du -sm "$dir" | cut -f1)
            
            log_info "清理缓存目录: $dir"
            
            if [ "$DRY_RUN" = true ]; then
                log_info "[DRY RUN] 将清理缓存: $dir"
            else
                # 清理包管理器缓存
                if command -v apt-get &> /dev/null; then
                    apt-get clean -y &> /dev/null || true
                    apt-get autoremove -y &> /dev/null || true
                elif command -v yum &> /dev/null; then
                    yum clean all -y &> /dev/null || true
                fi
                
                # 清理用户缓存
                find "$dir" -type f -mtime +7 -delete 2>/dev/null || true
            fi
            
            local size_after=$(du -sm "$dir" | cut -f1)
            local freed=$((size_before - size_after))
            total_size=$((total_size + freed))
            
            log_info "释放空间: ${freed}MB"
        fi
    done
    
    log_info "缓存文件清理完成,共释放: ${total_size}MB"
}

# 清理系统缓存
clean_system_cache() {
    log_info "===== 清理系统缓存 ====="
    
    local total_size=0
    
    # 清理页面缓存
    if [ "$DRY_RUN" = false ]; then
        sync
        echo 3 > /proc/sys/vm/drop_caches
        log_info "已清理页面缓存"
    else
        log_info "[DRY RUN] 将清理页面缓存"
    fi
    
    # 清理用户缓存
    for user_home in /home/*; do
        if [ -d "$user_home/.cache" ]; then
            local size_before=$(du -sm "$user_home/.cache" | cut -f1)
            
            if [ "$DRY_RUN" = true ]; then
                log_info "[DRY RUN] 将清理用户缓存: $user_home/.cache"
            else
                find "$user_home/.cache" -type f -mtime +7 -delete 2>/dev/null || true
            fi
            
            local size_after=$(du -sm "$user_home/.cache" | cut -f1)
            local freed=$((size_before - size_after))
            total_size=$((total_size + freed))
        fi
    done
    
    log_info "系统缓存清理完成,共释放: ${total_size}MB"
}

# 清理孤立文件
clean_orphaned_files() {
    log_info "===== 清理孤立文件 ====="
    
    local total_size=0
    
    # 查找并删除孤立包
    if command -v deborphan &> /dev/null; then
        local orphaned=$(deborphan | wc -l)
        if [ $orphaned -gt 0 ]; then
            if [ "$DRY_RUN" = true ]; then
                log_info "[DRY RUN] 发现 $orphaned 个孤立包"
            else
                deborphan | xargs apt-get -y remove &> /dev/null || true
                log_info "已删除 $orphaned 个孤立包"
            fi
        fi
    fi
    
    # 查找并删除孤立配置文件
    if command -v dpkg &> /dev/null; then
        local orphaned_configs=$(dpkg -l | grep '^rc' | wc -l)
        if [ $orphaned_configs -gt 0 ]; then
            if [ "$DRY_RUN" = true ]; then
                log_info "[DRY RUN] 发现 $orphaned_configs 个孤立配置文件"
            else
                dpkg -l | grep '^rc' | awk '{print $2}' | xargs dpkg --purge &> /dev/null || true
                log_info "已删除 $orphaned_configs 个孤立配置文件"
            fi
        fi
    fi
    
    log_info "孤立文件清理完成"
}

# 清理重复文件
clean_duplicate_files() {
    log_info "===== 查找重复文件 ====="
    
    # 查找重复文件(仅报告,不删除)
    find /home -type f -size +1M -exec md5sum {} \; | \
        sort | uniq -d -w 32 | \
        cut -d' ' -f3- | \
        while read -r file; do
            if [ -f "$file" ]; then
                log_info "发现重复文件: $file"
            fi
        done
    
    log_info "重复文件检查完成(仅报告)"
}

# 生成清理报告
generate_report() {
    local date=$(date +%Y-%m-%d)
    local report_file="/tmp/disk_cleanup_report_$date.txt"
    
    {
        echo "磁盘清理报告"
        echo "生成时间: $(date)"
        echo ""
        
        echo "===== 磁盘使用情况 ====="
        df -h
        echo ""
        
        echo "===== 大文件列表(>100MB)====="
        find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | head -20
        echo ""
        
        echo "===== 空目录列表 ====="
        find / -type d -empty 2>/dev/null | head -20
        echo ""
        
        echo "===== 清理统计 ====="
        echo "临时文件: 已清理"
        echo "日志文件: 已清理"
        echo "缓存文件: 已清理"
        echo "系统缓存: 已清理"
        echo "孤立文件: 已清理"
    } > "$report_file"
    
    log_info "清理报告已生成: $report_file"
}

# 主函数
main() {
    log_info "===== 开始磁盘清理 ====="
    
    # 检查磁盘空间
    check_disk_space
    
    # 执行清理
    clean_temp_files
    clean_log_files
    clean_cache_files
    clean_system_cache
    clean_orphaned_files
    clean_duplicate_files
    
    # 生成报告
    generate_report
    
    # 显示最终磁盘使用情况
    local final_usage=$(get_disk_usage)
    local final_free=$(get_free_space)
    log_info "===== 清理完成 ====="
    log_info "最终磁盘使用率: ${final_usage}%, 可用空间: ${final_free}GB"
    
    if [ "$DRY_RUN" = true ]; then
        log_info "[DRY RUN] 本次为试运行,未实际删除文件"
    fi
}

# 参数解析
while getopts "dvh" opt; do
    case $opt in
        d)
            DRY_RUN=true
            log_info "启用试运行模式"
            ;;
        v)
            VERBOSE=true
            log_info "启用详细输出"
            ;;
        h)
            echo "用法: $0 [选项]"
            echo "选项:"
            echo "  -d  试运行模式(不实际删除文件)"
            echo "  -v  详细输出"
            echo "  -h  显示帮助信息"
            exit 0
            ;;
        *)
            echo "无效选项: $opt"
            exit 1
            ;;
    esac
done

# 执行主函数
main "$@"

使用说明#

  1. 修改配置变量:

    • LOG_FILE: 日志文件路径
    • DRY_RUN: 试运行模式(true/false)
    • MIN_DISK_SPACE: 最小可用空间(GB)
    • TEMP_DIRS: 临时文件目录列表
    • LOG_DIRS: 日志文件目录列表
    • CACHE_DIRS: 缓存文件目录列表
  2. 添加执行权限:

    chmod +x disk_cleanup.sh
  3. 执行脚本:

    # 正常执行
    ./disk_cleanup.sh
    
    # 试运行模式(不实际删除文件)
    ./disk_cleanup.sh -d
    
    # 详细输出
    ./disk_cleanup.sh -v
  4. 设置定时任务(每周日凌晨3点执行):

    0 3 * * 0 /path/to/disk_cleanup.sh

功能特点#

  • 自动清理临时文件
  • 清理日志文件
  • 清理缓存文件
  • 清理系统缓存
  • 清理孤立文件
  • 查找重复文件
  • 磁盘空间检查
  • 详细的清理日志
  • 试运行模式
  • 清理报告生成

依赖项#

  • find: 用于查找文件
  • du: 用于计算磁盘使用
  • df: 用于显示磁盘使用情况
  • apt-get/yum: 用于包管理(根据系统选择)

注意事项#

  1. 建议先使用试运行模式(-d选项)查看将要删除的文件
  2. 清理前备份重要数据
  3. 根据实际情况调整清理策略
  4. 定期检查清理日志
  5. 某些清理操作可能需要root权限
  6. 清理系统缓存可能影响系统性能