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启动,查看实时运行日志,确认启动成功后使用后台命令,防止因为日志文件操作权限不足导致运行失败而无法查看运行日志

相关推荐
小涵6 小时前
第 01 天:Linux 是什么?内核、发行版及其生态系统
linux·运维·devops·1024程序员节·sre
sulikey6 小时前
Qt 入门简洁笔记:信号与槽
前端·c++·笔记·qt·前端框架·1024程序员节·qt框架
在等晚安么6 小时前
记录自己写项目的第三天,springbot+redis+rabbitma高并发项目
java·spring boot·redis·1024程序员节
SepstoneTang6 小时前
前端新手入门-HBuilder工具安装
html·html5·1024程序员节
WebKoalaBoy6 小时前
前端埋点学习
1024程序员节
羑悻的小杀马特6 小时前
告别内网限制!用StirlingPDF+cpolar打造可远程访问的PDF工具站
pdf·cpolar·1024程序员节·stirlingpdf
鸽鸽程序猿6 小时前
【算法】【动态规划】斐波那契数模型
算法·动态规划·1024程序员节
就是ping不通的蛋黄派6 小时前
CentOS7 部署主从复制MariaDB数据库
网络·1024程序员节
独行soc6 小时前
2025年渗透测试面试题总结-215(题目+回答)
网络·安全·web安全·adb·渗透测试·1024程序员节·安全狮