自动删除过期备份的脚本怎么写

wen 实用脚本 2

本文目录导读:

自动删除过期备份的脚本怎么写

  1. Linux Shell 脚本(最常用)
  2. 带文件名日期识别的脚本
  3. 使用 cron 定时执行的完整方案
  4. Python 脚本(更强大)
  5. 配置 crontab 定时执行
  6. 高级版:带邮件通知
  7. 使用建议

我来为您提供几个自动删除过期备份的脚本方案,根据不同的使用场景选择:

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. 先测试后生产:先在测试环境运行,确认逻辑正确
  2. 保留最少副本:至少保留最近1天的备份
  3. 设置权限:脚本执行权限 chmod +x script.sh
  4. 日志记录:记录所有操作,便于问题排查
  5. 监控告警:对删除数量设置阈值告警
  6. 定期检查:每月检查一次清理效果

选择哪种方案取决于您的实际需求、操作系统和备份策略,建议先用简单方案,逐渐优化。

抱歉,评论功能暂时关闭!