Shell脚本-定时备份

最近业务中常常需要编写一些脚本,故有此文,懒人必备~

#!/bin/bash
# 脚本名称: 定时备份
# 描述: 定时备份指定路径
# 版本: 1.0
# 作者: Cikaros
# 邮箱: Cikaros<at>qq.com
# 日期: 2025-07-02
# 版权: (C) 2025 Your Company. All rights reserved.
# === 配置参数 ===
# 默认配置(可被命令行参数覆盖)
BACKUP_PATHS=()                 # 要备份的路径列表
EXCLUDE_PATTERNS=()            # 排除规则列表
BACKUP_DIR="${HOME}/backups"   # 备份文件存储目录
RETENTION_DAYS=30              # 保留天数
LOG_FILE="/dev/stdout"         # 日志输出位置(可改为文件路径)

# === 函数定义 ===
show_help() {
    echo "用法: $0 -b <备份路径> [-b <更多路径>] [-e <排除路径>] [-d <备份目录>] [-r <保留天数>]"
    echo "示例: $0 -b /home/user/data -e /home/user/data/tmp -e /home/user/data/cache -d /backup -r 7"
    echo "选项:"
    echo "  -b  指定要备份的路径(可重复)"
    echo "  -e  指定排除规则(可重复)"
    echo "  -d  指定备份存储目录(默认: \$HOME/backups)"
    echo "  -r  指定保留天数(默认: 30)"
    echo "  -h  显示此帮助"
    exit 0
}

log_message() {
    local msg="$1"
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') - ${msg}" >> "${LOG_FILE}"
}

validate_paths() {
    local invalid=0
    for path in "${BACKUP_PATHS[@]}"; do
        if [ ! -e "${path}" ]; then
            log_message "警告: 备份路径不存在: ${path}"
            invalid=1
        fi
    done
    return "${invalid}"
}

create_backup() {
    local backup_filename="backup-$(date +%Y%m%d-%H%M%S).tar.gz"
    local full_path="${BACKUP_DIR}/${backup_filename}"
    
    log_message "开始创建备份: ${full_path}"
    
    # 创建备份目录(如果不存在)
    mkdir -p "${BACKUP_DIR}" || {
        log_message "错误: 无法创建备份目录: ${BACKUP_DIR}"
        return 1
    }
    
    # 构造tar命令
    local cmd=(tar -zcvf "${full_path}")
    cmd+=("${EXCLUDE_PATTERNS[@]}")
    cmd+=("${BACKUP_PATHS[@]}")
    
    # 执行备份
    if "${cmd[@]}"; then
        log_message "成功创建备份: ${full_path}"
        return 0
    else
        log_message "错误: 备份失败"
        return 1
    fi
}

cleanup_old_backups() {
    log_message "开始清理${RETENTION_DAYS}天前的备份..."
    
    find "${BACKUP_DIR}" -type f -name "*.tar.gz" -mtime "+${RETENTION_DAYS}" -exec \
        bash -c 'echo "删除旧备份: $1"; rm -f "$1"' _ {} \;
    
    log_message "清理完成"
}

# === 主程序 ===
main() {
    # 解析命令行参数
    while getopts ":b:e:d:r:h" opt; do
        case $opt in
            b) BACKUP_PATHS+=("$OPTARG") ;;
            e) EXCLUDE_PATTERNS+=("--exclude=$OPTARG") ;;
            d) BACKUP_DIR="$OPTARG" ;;
            r) RETENTION_DAYS="$OPTARG" ;;
            h) show_help ;;
            \?) 
                log_message "无效选项: -$OPTARG"
                show_help 
                exit 1
                ;;
        esac
    done

    # 参数验证
    if [ ${#BACKUP_PATHS[@]} -eq 0 ]; then
        log_message "错误: 未指定备份路径"
        show_help
        exit 1
    fi

    # 验证路径有效性
    validate_paths || exit 1

    # 执行备份
    create_backup || exit 1

    # 清理旧备份
    cleanup_old_backups
}

# === 执行入口 ===
main "$@"

Shell脚本-定时备份
https://blog.cikaros.top/doc/ae7603f.html
作者
Cikaros
发布于
2025年7月2日
许可协议