本文目录导读:

我来介绍几种Shell脚本自动清理过期备份文件的方法:
基础清理脚本(按天数删除)
#!/bin/bash # 备份文件目录 BACKUP_DIR="/path/to/backup" # 保留天数(保留7天) RETENTION_DAYS=7 # 清理过期文件 find "$BACKUP_DIR" -type f -mtime +$RETENTION_DAYS -delete # 清理空目录 find "$BACKUP_DIR" -type d -empty -delete echo "已清理 $RETENTION_DAYS 天前的备份文件"
增强版清理脚本(带日志和验证)
#!/bin/bash
# 配置
BACKUP_DIR="/var/backups"
RETENTION_DAYS=30
LOG_FILE="/var/log/backup_cleanup.log"
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# 验证目录存在
if [ ! -d "$BACKUP_DIR" ]; then
log "错误:备份目录 $BACKUP_DIR 不存在"
exit 1
fi
log "开始清理 $BACKUP_DIR 中超过 $RETENTION_DAYS 天的备份文件"
# 计算要删除的文件数量
FILES_TO_DELETE=$(find "$BACKUP_DIR" -type f -mtime +$RETENTION_DAYS | wc -l)
SIZE_TO_DELETE=$(find "$BACKUP_DIR" -type f -mtime +$RETENTION_DAYS -exec du -ch {} + | grep total$ | cut -f1)
log "找到 $FILES_TO_DELETE 个文件,共 $SIZE_TO_DELETE"
# 执行清理
find "$BACKUP_DIR" -type f -mtime +$RETENTION_DAYS -delete
# 清理空目录
find "$BACKUP_DIR" -type d -empty -delete
log "清理完成"
按文件名日期模式清理
#!/bin/bash
# 配置
BACKUP_DIR="/backups"
# 文件名格式:backup_2024-01-01.tar.gz
FILE_PATTERN="backup_*.tar.gz"
RETENTION_DAYS=7
# 当前日期
CURRENT_DATE=$(date +%Y-%m-%d)
for backup_file in "$BACKUP_DIR"/$FILE_PATTERN; do
if [ -f "$backup_file" ]; then
# 从文件名提取日期
FILE_DATE=$(echo "$backup_file" | grep -oP '\d{4}-\d{2}-\d{2}')
if [ -n "$FILE_DATE" ]; then
# 计算日期差
FILE_TIMESTAMP=$(date -d "$FILE_DATE" +%s)
CURRENT_TIMESTAMP=$(date +%s)
DAYS_DIFF=$(( (CURRENT_TIMESTAMP - FILE_TIMESTAMP) / 86400 ))
# 如果超过保留天数则删除
if [ $DAYS_DIFF -gt $RETENTION_DAYS ]; then
echo "删除过期文件: $backup_file (已保存 $DAYS_DIFF 天)"
rm -f "$backup_file"
fi
fi
fi
done
保留最新N个备份(按数量)
#!/bin/bash
# 配置
BACKUP_DIR="/backups"
# 保留最新的文件数(保留最新的5个)
KEEP_COUNT=5
FILE_PATTERN="backup_*"
# 获取按日期排序的文件列表(最新的在前)
FILES=$(ls -t "$BACKUP_DIR"/$FILE_PATTERN 2>/dev/null)
if [ -z "$FILES" ]; then
echo "没有找到备份文件"
exit 0
fi
COUNT=0
for file in $FILES; do
COUNT=$((COUNT + 1))
if [ $COUNT -gt $KEEP_COUNT ]; then
echo "删除旧备份: $file"
rm -f "$file"
fi
done
echo "保留最新的 $KEEP_COUNT 个备份文件"
综合清理脚本(多个策略)
#!/bin/bash
# 配置
BACKUP_DIR="/backups"
DAILY_RETENTION=7 # 保留7天每日备份
WEEKLY_RETENTION=4 # 保留4周每周备份
MONTHLY_RETENTION=3 # 保留3个月每月备份
BACKUP_PREFIX="backup"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
cleanup_daily() {
log "清理每日备份(保留 $DAILY_RETENTION 天)"
find "$BACKUP_DIR" -name "${BACKUP_PREFIX}_daily_*" -type f -mtime +$DAILY_RETENTION -delete
}
cleanup_weekly() {
log "清理每周备份(保留 $WEEKLY_RETENTION 周)"
# 获取所有周备份文件,按时间排序
find "$BACKUP_DIR" -name "${BACKUP_PREFIX}_weekly_*" -type f | sort -r | \
awk -v keep=$WEEKLY_RETENTION 'NR>keep {print}' | xargs -r rm -f
}
cleanup_monthly() {
log "清理每月备份(保留 $MONTHLY_RETENTION 个月)"
# 按月分组保留最新的
for month_dir in "$BACKUP_DIR"/${BACKUP_PREFIX}_monthly_*; do
[ -f "$month_dir" ] || continue
# 获取备份月份
month=$(echo "$month_dir" | grep -oP '\d{4}-\d{2}')
[ -z "$month" ] && continue
# 计算月份差
current_month=$(date +%Y-%m)
months_diff=$(( (($(date -d "$current_month-01" +%s) - $(date -d "$month-01" +%s)) / 2592000) ))
if [ $months_diff -ge $MONTHLY_RETENTION ]; then
log "删除过期月备份: $month_dir"
rm -f "$month_dir"
fi
done
}
# 执行清理
cleanup_daily
cleanup_weekly
cleanup_monthly
# 清理空目录
find "$BACKUP_DIR" -type d -empty -delete 2>/dev/null
log "备份清理完成"
使用crontab定时执行
# 编辑crontab crontab -e # 添加以下任一行(根据需要选择执行频率) # 每天凌晨2点执行清理 0 2 * * * /path/to/cleanup_script.sh # 每周日凌晨3点执行清理 0 3 * * 0 /path/to/cleanup_script.sh # 每月1日凌晨4点执行清理 0 4 1 * * /path/to/cleanup_script.sh
使用案例:备份后自动清理
#!/bin/bash # 创建备份 BACKUP_NAME="backup_$(date +%Y%m%d_%H%M%S).tar.gz" tar -czf "/backups/$BACKUP_NAME" /important/data/ # 调用清理脚本 /path/to/cleanup_script.sh echo "备份和清理完成"
使用建议
- 先测试:在正式使用前,先用
-delete换成-print预览要删除的文件 - 日志记录:保留清理日志以便审计
- 通知机制:可以添加邮件通知功能
- 权限控制:确保脚本有足够的删除权限
这样就能自动管理备份文件,避免磁盘空间被占满。