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