linux的文件备份脚本

  1. 准备auto_back.sh脚本
bash 复制代码
#!/bin/bash

# 增强版备份脚本 - 带详细注释
# 功能:每分钟备份一次,自动删除3分钟前的备份文件

# 设置脚本遇到错误时立即退出,防止错误累积
set -e

# =============================================================================
# 配置区域 - 用户可根据需要修改这些参数
# =============================================================================

# 配置文件路径(如果存在会优先读取配置文件)
CONFIG_FILE="/etc/backup_config.conf"

# 如果存在配置文件,则读取外部配置
if [ -f "$CONFIG_FILE" ]; then
    source "$CONFIG_FILE"
    echo "从配置文件 $CONFIG_FILE 加载配置"
else
    # 默认配置(当配置文件不存在时使用)
    
    # 需要备份的源目录路径
    BACKUP_SOURCE="/volume1/docker/mrdoc"
    
    # 备份文件存储目录路径
    BACKUP_DEST="/volume1/docker/back_mrdoc"
    
    # 备份文件名的前缀
    BACKUP_PREFIX="auto_backup_mrdoc"
    
	# 备份文件保留时间(天),超过这个时间的备份会被删除
    #RETENTION_DAYS=90
	RETENTION_MINUTES=3
    
    # 备份间隔时间(天)
    #BACKUP_INTERVAL_DAYS=30
	SLEEP_INTERVAL=60
    
    # 日志文件路径
    LOG_FILE="/var/log/auto_backup_mrdoc.log"
    
    # 检查间隔(秒)- 用于检查是否到达备份时间
    # CHECK_INTERVAL=86400  # 24小时检查一次
fi

# =============================================================================
# 函数定义区域
# =============================================================================

# 日志记录函数
# 参数:$1 - 要记录的日志信息
# 功能:将日志信息同时输出到屏幕和日志文件
log() {
    local log_message="$(date '+%Y-%m-%d %H:%M:%S') - $1"
    echo "$log_message" | tee -a "$LOG_FILE"
}

# 错误退出函数
# 参数:$1 - 错误信息
# 功能:记录错误日志并退出脚本
error_exit() {
    log "错误: $1"
    exit 1
}

# 依赖检查函数
# 功能:检查脚本运行所需的命令是否存在
check_dependencies() {
    # 检查 tar 命令是否可用
    command -v tar >/dev/null 2>&1 || error_exit "tar 命令未找到,请安装 tar 工具"
    
    # 检查 find 命令是否可用
    command -v find >/dev/null 2>&1 || error_exit "find 命令未找到"
    
    # 检查 date 命令是否可用
    command -v date >/dev/null 2>&1 || error_exit "date 命令未找到"
    
    log "所有依赖检查通过"
}

# 初始化函数
# 功能:执行脚本运行前的准备工作
initialize() {
    log "开始初始化备份服务..."
    
    # 检查系统依赖
    check_dependencies
    
    # 创建备份目录,如果目录不存在则创建
    # -p 参数确保父目录也会被创建,且如果目录已存在不会报错
    mkdir -p "$BACKUP_DEST" || error_exit "无法创建备份目录: $BACKUP_DEST"
    log "备份目录已准备: $BACKUP_DEST"
    
    # 创建日志文件所在目录
    mkdir -p "$(dirname "$LOG_FILE")" || error_exit "无法创建日志目录"
    log "日志目录已准备: $(dirname "$LOG_FILE")"
    
    # 检查源目录是否存在(如果不是强制性要求,可以改为警告)
    if [ ! -e "$BACKUP_SOURCE" ]; then
        log "警告: 源目录不存在: $BACKUP_SOURCE,备份可能失败"
    else
        log "源目录检查通过: $BACKUP_SOURCE"
    fi
    
    log "=== 备份服务配置汇总 ==="
    log "源目录: $BACKUP_SOURCE"
    log "目标目录: $BACKUP_DEST"
    log "备份前缀: $BACKUP_PREFIX"
    log "保留时间: ${RETENTION_MINUTES} 分钟"
    log "备份间隔: ${SLEEP_INTERVAL} 秒"
    log "日志文件: $LOG_FILE"
    log "========================="
    
    log "备份服务初始化完成"
}

# 执行备份函数
# 功能:创建新的备份文件
# 返回值:0-成功,1-失败
perform_backup() {
    # 生成时间戳,格式:年月日_时分秒
    local timestamp=$(date +"%Y%m%d_%H%M%S")
    
    # 构建备份文件完整路径
    local backup_file="${BACKUP_DEST}/${BACKUP_PREFIX}_${timestamp}.tar.gz"
    
    log "开始创建备份: $backup_file"
    
    # 检查源目录是否存在
    if [ ! -e "$BACKUP_SOURCE" ]; then
        log "错误: 源目录不存在,跳过本次备份: $BACKUP_SOURCE"
        return 1  # 返回非0表示失败,但不会退出脚本(因为被调用处处理)
    fi
    
    # 执行备份命令说明:
    # tar -czf: 
    #   c - 创建归档
    #   z - 使用gzip压缩
    #   f - 指定文件名
    # -C "$(dirname "$BACKUP_SOURCE")": 切换到此目录
    # "$(basename "$BACKUP_SOURCE")": 备份这个文件/目录
    # 2>/dev/null: 将错误输出重定向到空设备(静默模式)
    if tar -czf "$backup_file" -C "$(dirname "$BACKUP_SOURCE")" "$(basename "$BACKUP_SOURCE")" 2>/dev/null; then
        # 获取备份文件大小(人类可读格式)
        local file_size=$(du -h "$backup_file" | cut -f1)
        log "备份成功: $backup_file (大小: ${file_size})"
        return 0  # 返回0表示成功
    else
        log "备份失败: $backup_file"
        # 删除可能创建的不完整备份文件
        rm -f "$backup_file"
        return 1  # 返回非0表示失败
    fi
}

# 清理旧备份函数
# 功能:删除超过保留时间的备份文件
cleanup_old_backups() {
    log "开始清理 ${RETENTION_MINUTES} 分钟前的备份文件..."
    
    # 使用 find 命令查找并删除旧备份文件:
    # find "$BACKUP_DEST": 在备份目录中查找
    # -name "${BACKUP_PREFIX}_*.tar.gz": 匹配备份文件名模式
    # -mmin "+${RETENTION_MINUTES}": 查找修改时间在 RETENTION_MINUTES 分钟之前的文件
    # -delete: 删除找到的文件
    # -print: 打印被删除的文件名
    local deleted_count=$(find "$BACKUP_DEST" -name "${BACKUP_PREFIX}_*.tar.gz" -mmin "+${RETENTION_MINUTES}" -delete -print | wc -l)
    
    if [ $deleted_count -gt 0 ]; then
        log "清理完成: 已删除 $deleted_count 个过期备份文件"
    else
        log "清理完成: 没有需要删除的过期备份文件"
    fi
}

# 显示状态函数
# 功能:显示当前备份状态和文件列表
show_status() {
    # 统计当前备份文件数量
    local backup_count=$(find "$BACKUP_DEST" -name "${BACKUP_PREFIX}_*.tar.gz" 2>/dev/null | wc -l)
    log "当前备份状态: 共有 $backup_count 个备份文件"
    
    # 如果有备份文件,显示最新的5个
    if [ $backup_count -gt 0 ]; then
        log "最新的备份文件列表:"
        # 查找备份文件并按时间倒序排列,显示前5个
        find "$BACKUP_DEST" -name "${BACKUP_PREFIX}_*.tar.gz" -printf "%T+ %p\n" | sort -r | head -5 | while read line; do
            log "  $line"
        done
    else
        log "当前没有备份文件"
    fi
}

# 磁盘空间检查函数(新增)
# 功能:检查备份目录所在磁盘的空间使用情况
check_disk_space() {
    # 获取备份目录的磁盘使用情况
    # df -h: 显示磁盘空间使用情况(人类可读格式)
    # grep: 筛选出包含备份目录所在行的信息
    local disk_info=$(df -h "$BACKUP_DEST" | tail -1)
    local available_space=$(echo "$disk_info" | awk '{print $4}')
    local usage_percent=$(echo "$disk_info" | awk '{print $5}')
    
    log "磁盘空间状态: 可用空间 $available_space, 使用率 $usage_percent"
    
    # 如果使用率超过90%,发出警告
    if [[ "${usage_percent%"%"}" -gt 90 ]]; then
        log "警告: 磁盘空间不足,使用率已超过90%!"
    fi
}

# =============================================================================
# 主循环函数
# =============================================================================

main() {
    # 执行初始化
    initialize
    
    # 显示初始磁盘空间状态
    check_disk_space
    
    log "开始主备份循环..."
    
    # 无限循环,直到脚本被终止
    while true; do
        # 记录循环开始时间
        local cycle_start=$(date +%s)
        
        log "开始新一轮备份周期..."
        
        # 执行备份
        if perform_backup; then
            # 备份成功后清理旧文件
            cleanup_old_backups
        else
            log "备份失败,跳过本次清理操作"
        fi
        
        # 显示当前状态
        show_status
        
        # 定期检查磁盘空间(每10次循环检查一次)
        local current_cycle=$(( (cycle_start - $(date -d "today 00:00" +%s)) / SLEEP_INTERVAL ))
        if [ $((current_cycle % 10)) -eq 0 ]; then
            check_disk_space
        fi
        
        # 计算实际耗时,确保准确的休眠间隔
        local cycle_end=$(date +%s)
        local cycle_duration=$((cycle_end - cycle_start))
        local actual_sleep=$((SLEEP_INTERVAL - cycle_duration))
        
        # 如果实际耗时超过间隔时间,立即开始下一轮
        if [ $actual_sleep -lt 0 ]; then
            log "警告: 备份周期耗时 ${cycle_duration} 秒,超过间隔时间 ${SLEEP_INTERVAL} 秒"
            actual_sleep=0
        else
            log "本次备份周期耗时 ${cycle_duration} 秒"
        fi
        
        log "等待 ${actual_sleep} 秒后开始下一轮备份..."
        echo "=========================================="
        
        # 等待指定时间
        sleep $actual_sleep
    done
}

# =============================================================================
# 信号处理设置
# =============================================================================

# 设置信号处理,当收到终止信号时优雅地退出脚本
# SIGTERM (15): 正常终止信号
# SIGINT (2):   Ctrl+C 中断信号
trap 'log "收到终止信号,备份服务正在停止..."; exit 0' SIGTERM SIGINT

# SIGHUP (1):  终端挂断信号(重新加载配置)
trap 'log "收到挂断信号,配置可能已更新"' SIGHUP

# =============================================================================
# 脚本入口点
# =============================================================================

# 显示脚本启动信息
echo "=========================================="
echo "增强版自动备份脚本启动"
echo "当前时间: $(date)"
echo "进程ID: $$"
echo "=========================================="

# 执行主函数
main

# 脚本正常结束(实际上主函数是无限循环,不会执行到这里)
log "备份服务意外结束"
exit 0
  1. 脚本使用相关命令
bash 复制代码
1.去除文件windows修改后产生的空格或跨行符等
sed -i 's/\r$//' back_mrdoc.sh

2.加权限
chmod +x back_mrdoc.sh

3.启动脚本
窗口:./back_mrdoc.sh
后台:nohup ./back_mrdoc.sh > /dev/null 2>&1 &

4.查看脚本运行
pa -aux | grep back_mrdoc.sh

5.停止脚本进程
kill -9 pid

6.查看日志
tail -f /var/log/back_mrdoc.log

注意:启动时建议先./back_mrdoc.sh启动,查看实时运行日志,确认启动成功后使用后台命令,防止因为日志文件操作权限不足导致运行失败而无法查看运行日志

相关推荐
fangzhanpeng1681 天前
快速掌握C#语言基础知识点(1.基础数据类型)
开发语言·c#·1024程序员节
无己心3 天前
面向多平台 AI 搜索引擎的适配层架构设计
前端·人工智能·搜索引擎·ai·1024程序员节
u0103055279 天前
AI驱动的安卓UI自动生成功能实现
人工智能·1024程序员节
u01030552710 天前
长株潭智能体赋能腾讯元器链接共享
1024程序员节
云贝贝贝11 天前
OceanBase认证体系介绍与备考指南
运维·服务器·oceanbase·1024程序员节
u01030552711 天前
Java图像处理实战指南
人工智能·1024程序员节
u01030552712 天前
Java AWT鼠标事件全解析
人工智能·1024程序员节
u01030552714 天前
Java实用类应用精讲
人工智能·1024程序员节
u01030552715 天前
Java I/O核心操作实战
人工智能·1024程序员节
u01030552716 天前
ArrayList操作详解与实战应用
人工智能·1024程序员节