本文目录导读:

我来为您提供几个自动删除过期备份的脚本方案,根据不同的使用场景选择:
Linux Shell 脚本(最常用)
#!/bin/bash
# 备份目录
BACKUP_DIR="/path/to/backup"
# 保留天数
RETENTION_DAYS=7
# 日志文件
LOG_FILE="/var/log/backup_cleanup.log"
# 记录日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# 检查目录是否存在
if [ ! -d "$BACKUP_DIR" ]; then
log "错误:备份目录不存在 - $BACKUP_DIR"
exit 1
fi
log "开始清理过期备份文件..."
log "备份目录: $BACKUP_DIR"
log "保留天数: $RETENTION_DAYS"
# 查找并删除过期文件
DELETED_COUNT=0
for file in $(find "$BACKUP_DIR" -type f -mtime +$RETENTION_DAYS); do
rm -f "$file"
log "已删除: $file"
DELETED_COUNT=$((DELETED_COUNT + 1))
done
log "清理完成,共删除 $DELETED_COUNT 个文件"
带文件名日期识别的脚本
#!/bin/bash
# 处理包含日期格式的文件名,如 backup_2024-01-01.tar.gz
BACKUP_DIR="/path/to/backup"
RETENTION_DAYS=7
# 当前时间和阈值时间
CURRENT_TIME=$(date +%s)
THRESHOLD_TIME=$((CURRENT_TIME - RETENTION_DAYS * 24 * 60 * 60))
for file in "$BACKUP_DIR"/backup_*.tar.gz; do
if [ -f "$file" ]; then
# 提取文件名中的日期
filename=$(basename "$file")
# 假设格式为 backup_YYYY-MM-DD.tar.gz
file_date=$(echo "$filename" | grep -oP '\d{4}-\d{2}-\d{2}')
if [ ! -z "$file_date" ]; then
# 转换为时间戳
file_timestamp=$(date -d "$file_date" +%s 2>/dev/null)
# 判断是否过期
if [ "$file_timestamp" -lt "$THRESHOLD_TIME" ]; then
echo "删除过期备份: $file"
rm -f "$file"
fi
fi
fi
done
使用 cron 定时执行的完整方案
#!/bin/bash
# 配置变量
BACKUP_ROOT="/var/backups"
KEEP_DAILY=7 # 保留最近7天
KEEP_WEEKLY=4 # 保留最近4周的周备份
KEEP_MONTHLY=3 # 保留最近3个月的月备份
# 获取当前时间信息
CURRENT_DATE=$(date +%Y%m%d)
CURRENT_DOW=$(date +%u) # 星期几 (1-7)
CURRENT_DOM=$(date +%d) # 每月第几天
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# 按保留策略删除
cleanup_by_policy() {
local dir=$1
local days=$2
local prefix=$3
log "清理 $prefix 类型的备份(保留 $days 天)"
find "$dir" -name "${prefix}*" -type f -mtime +"$days" -exec rm -f {} \;
}
# 执行清理
log "=== 开始备份清理 ==="
# 清理日备份(保留7天)
if [ "$CURRENT_DOW" != "7" ]; then
cleanup_by_policy "$BACKUP_ROOT/daily" "$KEEP_DAILY" "daily"
fi
# 清理周备份(保留4周)
if [ "$CURRENT_DOW" = "7" ] && [ "$CURRENT_DOM" -lt 8 ]; then
cleanup_by_policy "$BACKUP_ROOT/weekly" "$((KEEP_WEEKLY * 7))" "weekly"
fi
# 清理月备份(保留3个月)
if [ "$CURRENT_DOM" = "01" ]; then
cleanup_by_policy "$BACKUP_ROOT/monthly" "$((KEEP_MONTHLY * 30))" "monthly"
fi
log "=== 备份清理完成 ==="
Python 脚本(更强大)
#!/usr/bin/env python3
import os
import time
import glob
import logging
from datetime import datetime, timedelta
from pathlib import Path
# 配置
BACKUP_DIR = "/path/to/backup"
RETENTION_DAYS = 7
FILE_PATTORN = "*.tar.gz"
# 设置日志
logging.basicConfig(
filename='/var/log/backup_cleanup.log',
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
def cleanup_backups():
"""清理过期备份"""
cutoff_date = datetime.now() - timedelta(days=RETENTION_DAYS)
cutoff_timestamp = cutoff_date.timestamp()
deleted_count = 0
freed_space = 0
logging.info(f"开始清理,保留 {RETENTION_DAYS} 天内的备份")
for file_path in glob.glob(os.path.join(BACKUP_DIR, FILE_PATTORN)):
try:
file_timestamp = os.path.getmtime(file_path)
if file_timestamp < cutoff_timestamp:
file_size = os.path.getsize(file_path)
os.remove(file_path)
deleted_count += 1
freed_space += file_size
logging.info(f"已删除: {file_path} ({file_size/1024/1024:.2f} MB)")
except Exception as e:
logging.error(f"处理文件 {file_path} 时出错: {str(e)}")
logging.info(f"清理完成: 删除 {deleted_count} 个文件,释放 {freed_space/1024/1024:.2f} MB 空间")
if __name__ == "__main__":
cleanup_backups()
配置 crontab 定时执行
# 每天凌晨2点执行清理 0 2 * * * /usr/local/bin/cleanup_backups.sh # 每周日凌晨3点执行 0 3 * * 0 /usr/local/bin/cleanup_backups.sh # 每月1号凌晨4点执行 0 4 1 * * /usr/local/bin/cleanup_backups.py
高级版:带邮件通知
#!/bin/bash
# 邮件通知配置
EMAIL_TO="admin@example.com"
SMTP_SERVER="smtp.example.com"
BACKUP_DIR="/path/to/backup"
RETENTION_DAYS=7
# 计算清理前的空间使用
TOTAL_SIZE_BEFORE=$(du -sh "$BACKUP_DIR" | awk '{print $1}')
# 清理过期备份
DELETED_FILES=$(find "$BACKUP_DIR" -type f -mtime +$RETENTION_DAYS -name "*.back" | while read file; do
echo "$file"
rm -f "$file"
done)
# 计算清理后的空间
TOTAL_SIZE_AFTER=$(du -sh "$BACKUP_DIR" | awk '{print $1}')
# 发送邮件通知
if [ ! -z "$DELETED_FILES" ]; then
mail -s "备份清理完成 | 空间从 $TOTAL_SIZE_BEFORE 到 $TOTAL_SIZE_AFTER" "$EMAIL_TO" <<EOF
备份清理已经完成。
删除的文件:
$(echo "$DELETED_FILES")
备份目录空间变化:
之前: $TOTAL_SIZE_BEFORE
之后: $TOTAL_SIZE_AFTER
EOF
fi
使用建议
- 先测试后生产:先在测试环境运行,确认逻辑正确
- 保留最少副本:至少保留最近1天的备份
- 设置权限:脚本执行权限
chmod +x script.sh - 日志记录:记录所有操作,便于问题排查
- 监控告警:对删除数量设置阈值告警
- 定期检查:每月检查一次清理效果
选择哪种方案取决于您的实际需求、操作系统和备份策略,建议先用简单方案,逐渐优化。