Cloudflare R2备份脚本

📜 完整脚本源码

#!/bin/bash

# Cloudflare R2备份脚本
# 支持交互式选择和命令行参数调用
# 使用方法: sh r2_backup.sh [选项]
# 选项: 1 - 全量备份

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# R2配置变量
R2_BUCKET_NAME="bucket_name"
R2_ENDPOINT="https://xxx.r2.cloudflarestorage.com"
R2_ACCESS_KEY_ID="xxx"
R2_ACCESS_KEY_SECRET="xxx"
R2_REGION="WNAM"
R2_REMOTE_NAME="cloudflare-r2"

# 备份配置
BACKUP_TARGET_DIR="/home/r2_backup_$(date +%Y%m%d_%H%M%S)"  # 本地备份目录(带时间戳)
# 备份整个存储桶,保持完整目录结构

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查rclone是否已安装
check_rclone() {
    log_info "检查rclone是否已安装..."
    
    if command -v rclone &> /dev/null; then
        local version=$(rclone version | head -n 1)
        log_success "rclone已安装: $version"
        return 0
    else
        log_warning "rclone未安装"
        return 1
    fi
}

# 安装rclone
install_rclone() {
    log_info "开始安装rclone..."
    
    # 检查系统类型
    if [[ -f /etc/redhat-release ]] || [[ -f /etc/centos-release ]] || [[ -f /etc/alios-release ]]; then
        # CentOS/RHEL/Alibaba Cloud Linux
        log_info "检测到CentOS/RHEL/Alibaba Cloud Linux系统"
        
        # 使用官方推荐的安装方法
        curl https://rclone.org/install.sh | sudo bash
        
        if [[ $? -eq 0 ]]; then
            log_success "rclone安装成功"
        else
            log_error "rclone安装失败"
            exit 1
        fi
    else
        log_error "不支持的系统类型,请手动安装rclone"
        exit 1
    fi
}

# 配置rclone for Cloudflare R2
configure_rclone() {
    log_info "配置rclone连接到Cloudflare R2..."
    
    # 检查配置是否已存在,静默覆盖
    if rclone listremotes | grep -q "^${R2_REMOTE_NAME}:$"; then
        log_info "rclone配置 '${R2_REMOTE_NAME}' 已存在,将更新配置"
    fi
    
    # 创建rclone配置
    log_info "创建rclone配置文件..."
    
    # 确保配置目录存在
    mkdir -p ~/.config/rclone
    
    # 生成配置内容
    cat > ~/.config/rclone/rclone.conf << EOF
[${R2_REMOTE_NAME}]
type = s3
provider = Cloudflare
access_key_id = ${R2_ACCESS_KEY_ID}
secret_access_key = ${R2_ACCESS_KEY_SECRET}
region = ${R2_REGION}
endpoint = ${R2_ENDPOINT}
acl = private
EOF

    # 测试连接
    log_info "测试rclone连接..."
    if rclone lsd ${R2_REMOTE_NAME}: &> /dev/null; then
        log_success "rclone配置成功,连接测试通过"
    else
        log_error "rclone配置失败,连接测试未通过"
        exit 1
    fi
}

# 全量备份函数
full_backup() {
    log_info "开始执行全量备份..."
    log_info "备份源: ${R2_REMOTE_NAME}:${R2_BUCKET_NAME}/ (整个存储桶)"
    log_info "备份目标目录: ${BACKUP_TARGET_DIR}"
    
    # 创建本地备份目录
    mkdir -p "${BACKUP_TARGET_DIR}"
    
    # 创建备份日志目录
    local log_dir="/var/log/r2_backup"
    sudo mkdir -p "$log_dir"
    local log_file="$log_dir/backup_$(date +%Y%m%d_%H%M%S).log"
    
    # 执行备份 - 备份整个存储桶,保持完整目录结构
    log_info "开始从Cloudflare R2同步整个存储桶到本地..."
    
    rclone sync "${R2_REMOTE_NAME}:${R2_BUCKET_NAME}/" "${BACKUP_TARGET_DIR}/" \
        --progress \
        --transfers 4 \
        --checkers 8 \
        --retries 3 \
        --low-level-retries 10 \
        --stats 30s \
        --log-file "$log_file" \
        --log-level INFO
    
    if [[ $? -eq 0 ]]; then
        log_success "全量备份完成"
        log_info "备份日志: $log_file"
        
        # 显示备份统计信息
        log_info "获取备份统计信息..."
        rclone size "${R2_REMOTE_NAME}:${R2_BUCKET_NAME}/${BACKUP_REMOTE_DIR}"
    else
        log_error "全量备份失败"
        log_error "请查看日志文件: $log_file"
        exit 1
    fi
}

# 显示菜单
show_menu() {
    echo
    echo "=================================="
    echo "  Cloudflare R2 数据备份工具"
    echo "  (从R2下载数据到本地服务器)"
    echo "=================================="
    echo "1. 全量备份 (从R2同步到本地)"
    echo "2. 查看备份状态"
    echo "3. 测试R2连接"
    echo "4. 删除R2目录"
    echo "5. 重新配置rclone"
    echo "0. 退出"
    echo "=================================="
}

# 查看备份列表
list_backups() {
    log_info "查看备份列表..."
    
    echo
    echo "=== 本地备份目录 ==="
    if [[ -d "${BACKUP_TARGET_DIR}" ]]; then
        ls -la "${BACKUP_TARGET_DIR}"
        echo
        echo "备份目录大小:"
        du -sh "${BACKUP_TARGET_DIR}"
    else
        echo "本地备份目录不存在: ${BACKUP_TARGET_DIR}"
    fi
    
    echo
    echo "=== R2存储桶内容 ==="
    rclone lsd "${R2_REMOTE_NAME}:${R2_BUCKET_NAME}" --max-depth 2
}

# 测试连接
test_connection() {
    log_info "测试Cloudflare R2连接..."
    if rclone lsd "${R2_REMOTE_NAME}:" &> /dev/null; then
        log_success "连接测试成功"
        rclone about "${R2_REMOTE_NAME}:"
    else
        log_error "连接测试失败"
    fi
}

# 删除R2存储桶中的指定顶层目录
delete_directory() {
    log_info "删除R2存储桶中的顶层目录..."
    
    echo
    echo "=== R2存储桶顶层目录列表 ==="
    
    # 获取顶层目录列表
    local dirs=$(rclone lsd "${R2_REMOTE_NAME}:${R2_BUCKET_NAME}" --max-depth 1 2>/dev/null | awk '{print $5}' | grep -v '^$')
    
    if [[ -z "$dirs" ]]; then
        log_warning "存储桶中没有找到任何目录"
        return 1
    fi
    
    # 显示目录列表
    local dir_array=()
    local index=1
    while IFS= read -r dir; do
        if [[ -n "$dir" ]]; then
            echo "$index. $dir"
            dir_array+=("$dir")
            ((index++))
        fi
    done <<< "$dirs"
    
    echo "0. 取消操作"
    echo
    
    # 用户选择
    read -p "请选择要删除的目录编号 [0-$((index-1))]: " choice
    
    # 验证输入
    if [[ ! "$choice" =~ ^[0-9]+$ ]] || [[ "$choice" -lt 0 ]] || [[ "$choice" -ge "$index" ]]; then
        log_error "无效的选择"
        return 1
    fi
    
    # 取消操作
    if [[ "$choice" -eq 0 ]]; then
        log_info "取消删除操作"
        return 0
    fi
    
    # 获取选择的目录
    local selected_dir="${dir_array[$((choice-1))]}"
    
    # 二次确认
    echo
    log_warning "警告:即将删除目录 '${selected_dir}' 及其所有内容"
    log_warning "此操作不可逆!"
    read -p "确认删除? 请输入 'DELETE' 来确认: " confirm
    
    if [[ "$confirm" != "DELETE" ]]; then
        log_info "取消删除操作"
        return 0
    fi
    
    # 执行删除
    log_info "正在删除目录: ${selected_dir}"
    
    if rclone purge "${R2_REMOTE_NAME}:${R2_BUCKET_NAME}/${selected_dir}" 2>/dev/null; then
        log_success "目录 '${selected_dir}' 删除成功"
    else
        log_error "目录 '${selected_dir}' 删除失败"
        return 1
    fi
}

# 主函数
main() {
    echo "Cloudflare R2备份脚本启动..."
    
    # 处理命令行参数 - 直接执行模式
    if [[ $# -gt 0 ]]; then
        # 检查并安装rclone
        if ! check_rclone; then
            install_rclone
        fi
        
        # 配置rclone
        configure_rclone
        
        case $1 in
            1)
                full_backup
                exit 0
                ;;
            2)
                list_backups
                exit 0
                ;;
            3)
                test_connection
                exit 0
                ;;
            4)
                delete_directory
                exit 0
                ;;
            5)
                configure_rclone
                exit 0
                ;;
            *)
                log_error "无效的参数: $1"
                echo "使用方法: $0 [1|2|3|4|5]"
                echo "1 - 全量备份"
                echo "2 - 查看备份列表"
                echo "3 - 测试连接"
                echo "4 - 删除R2目录"
                echo "5 - 重新配置rclone"
                exit 1
                ;;
        esac
    fi
    
    # 交互式菜单模式
    while true; do
        show_menu
        read -p "请选择操作 [0-4]: " choice
        
        case $choice in
            1)
                # 检查并安装rclone
                if ! check_rclone; then
                    install_rclone
                fi
                # 配置rclone
                configure_rclone
                full_backup
                ;;
            2)
                # 检查并安装rclone
                if ! check_rclone; then
                    install_rclone
                fi
                # 配置rclone
                configure_rclone
                list_backups
                ;;
            3)
                # 检查并安装rclone
                if ! check_rclone; then
                    install_rclone
                fi
                # 配置rclone
                configure_rclone
                test_connection
                ;;
            4)
                # 检查并安装rclone
                if ! check_rclone; then
                    install_rclone
                fi
                # 配置rclone
                configure_rclone
                delete_directory
                ;;
            5)
                # 检查并安装rclone
                if ! check_rclone; then
                    install_rclone
                fi
                configure_rclone
                ;;
            0)
                log_info "退出程序"
                exit 0
                ;;
            *)
                log_error "无效选择,请重新输入"
                ;;
        esac
        
        echo
        read -p "按回车键继续..." -r
    done
}

# 脚本入口
main "$@"

📋 项目介绍

这是一个功能完整的 Cloudflare R2 存储桶管理工具,支持数据备份、目录删除等操作。该脚本基于 rclone 工具开发,提供了友好的交互式界面和命令行参数支持。

✨ 功能特性

  • 🔄 全量备份: 从 Cloudflare R2 存储桶同步数据到本地服务器
  • 📊 状态查看: 查看本地备份和远程存储桶状态
  • 🔗 连接测试: 测试与 Cloudflare R2 的连接状态
  • 🗑️ 目录删除: 安全删除 R2 存储桶中的指定目录
  • ⚙️ 配置管理: 自动安装和配置 rclone
  • 📝 日志记录: 详细的操作日志和彩色输出
  • 🎛️ 双模式支持: 交互式菜单 + 命令行参数

🛠️ 环境要求

系统支持

  • CentOS 7+
  • RHEL 7+
  • Alibaba Cloud Linux
  • 其他 Linux 发行版(需手动安装 rclone)

依赖工具

  • curl - 用于下载 rclone
  • sudo - 管理员权限
  • bash - Shell 解释器

📋 配置说明

R2 配置参数

在使用脚本前,需要修改以下配置变量:

R2_BUCKET_NAME="your-bucket-name"           # R2 存储桶名称
R2_ENDPOINT="https://xxx.r2.cloudflarestorage.com"  # R2 端点地址
R2_ACCESS_KEY_ID="your-access-key"          # 访问密钥 ID
R2_ACCESS_KEY_SECRET="your-secret-key"      # 访问密钥
R2_REGION="WNAM"                            # 区域设置

获取 R2 配置信息

  1. 登录 Cloudflare Dashboard
  2. 进入 R2 Object Storage
  3. 选择您的存储桶
  4. Settings 中获取端点地址
  5. API tokens 中创建并获取访问密钥

🚀 使用方法

交互式模式

# 启动交互式菜单
sh r2_backup.sh

命令行模式

# 全量备份
sh r2_backup.sh 1

# 查看备份状态
sh r2_backup.sh 2

# 测试连接
sh r2_backup.sh 3

# 删除R2目录
sh r2_backup.sh 4

# 重新配置rclone
sh r2_backup.sh 5

📖 功能详解

1. 全量备份

  • 从 R2 存储桶完整同步数据到本地
  • 保持原有目录结构
  • 自动创建带时间戳的备份目录
  • 支持断点续传和重试机制

2. 查看备份状态

  • 显示本地备份目录内容和大小
  • 展示 R2 存储桶结构
  • 提供详细的统计信息

3. 测试连接

  • 验证 rclone 配置正确性
  • 测试网络连接状态
  • 显示存储桶基本信息

4. 删除 R2 目录

  • 列出存储桶顶层目录
  • 交互式选择删除目标
  • 二次确认防止误操作
  • 安全删除指定目录及内容

5. 配置管理

  • 自动检测和安装 rclone
  • 生成 R2 连接配置
  • 验证配置有效性

📂 目录结构

/home/r2_backup_YYYYMMDD_HHMMSS/    # 备份根目录
├── [存储桶内容]                     # 保持原有结构
/var/log/r2_backup/                 # 日志目录
├── backup_YYYYMMDD_HHMMSS.log      # 备份日志
~/.config/rclone/                   # rclone配置
├── rclone.conf                     # 配置文件

⚠️ 注意事项

安全提醒

  • 访问密钥安全: 确保 R2 访问密钥的安全性,不要泄露
  • 删除确认: 删除操作不可逆,请谨慎操作
  • 权限管理: 脚本需要 sudo 权限进行系统操作

性能优化

  • 网络带宽: 大文件传输需要稳定的网络环境
  • 存储空间: 确保本地有足够的存储空间
  • 并发设置: 可根据服务器性能调整 --transfers--checkers 参数

备份策略

  • 定期备份: 建议设置定时任务进行定期备份
  • 监控日志: 定期检查备份日志确保操作成功
  • 版本管理: 考虑实现备份版本管理机制

🛠️ 故障排除

常见问题

Q: rclone 安装失败

# 手动安装 rclone
curl https://rclone.org/install.sh | sudo bash

Q: 连接测试失败

  • 检查网络连接
  • 验证 R2 配置参数
  • 确认访问密钥权限

Q: 备份中断

  • 检查磁盘空间
  • 查看网络状态
  • 重新运行备份命令

Q: 权限不足

# 确保脚本有执行权限
chmod +x r2_backup.sh

日志分析

备份日志位于 /var/log/r2_backup/ 目录下,包含详细的操作记录:

# 查看最新日志
tail -f /var/log/r2_backup/backup_*.log

# 搜索错误信息
grep -i error /var/log/r2_backup/backup_*.log

🔧 高级配置

自定义 rclone 参数

可在脚本中修改以下参数以优化性能:

--transfers 4          # 并发传输数量
--checkers 8          # 并发检查器数量
--retries 3           # 重试次数
--low-level-retries 10 # 底层重试次数
--stats 30s           # 统计更新间隔

定时备份设置

使用 crontab 设置定时备份:

# 编辑 crontab
crontab -e

# 每天凌晨 2 点执行全量备份
0 2 * * * /path/to/r2_backup.sh 1 >> /var/log/r2_backup/cron.log 2>&1

📜 完整脚本源码

#!/bin/bash

# Cloudflare R2备份脚本
# 支持交互式选择和命令行参数调用
# 使用方法: sh r2_backup.sh [选项]
# 选项: 1 - 全量备份

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# R2配置变量
R2_BUCKET_NAME="twenhub-bucket"
R2_ENDPOINT="https://xxx.r2.cloudflarestorage.com"
R2_ACCESS_KEY_ID="xxx"
R2_ACCESS_KEY_SECRET="xxx"
R2_REGION="WNAM"
R2_REMOTE_NAME="cloudflare-r2"

# 备份配置
BACKUP_TARGET_DIR="/home/r2_backup_$(date +%Y%m%d_%H%M%S)"  # 本地备份目录(带时间戳)
# 备份整个存储桶,保持完整目录结构

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查rclone是否已安装
check_rclone() {
    log_info "检查rclone是否已安装..."
    
    if command -v rclone &> /dev/null; then
        local version=$(rclone version | head -n 1)
        log_success "rclone已安装: $version"
        return 0
    else
        log_warning "rclone未安装"
        return 1
    fi
}

# 安装rclone
install_rclone() {
    log_info "开始安装rclone..."
    
    # 检查系统类型
    if [[ -f /etc/redhat-release ]] || [[ -f /etc/centos-release ]] || [[ -f /etc/alios-release ]]; then
        # CentOS/RHEL/Alibaba Cloud Linux
        log_info "检测到CentOS/RHEL/Alibaba Cloud Linux系统"
        
        # 使用官方推荐的安装方法
        curl https://rclone.org/install.sh | sudo bash
        
        if [[ $? -eq 0 ]]; then
            log_success "rclone安装成功"
        else
            log_error "rclone安装失败"
            exit 1
        fi
    else
        log_error "不支持的系统类型,请手动安装rclone"
        exit 1
    fi
}

# 配置rclone for Cloudflare R2
configure_rclone() {
    log_info "配置rclone连接到Cloudflare R2..."
    
    # 检查配置是否已存在,静默覆盖
    if rclone listremotes | grep -q "^${R2_REMOTE_NAME}:$"; then
        log_info "rclone配置 '${R2_REMOTE_NAME}' 已存在,将更新配置"
    fi
    
    # 创建rclone配置
    log_info "创建rclone配置文件..."
    
    # 确保配置目录存在
    mkdir -p ~/.config/rclone
    
    # 生成配置内容
    cat > ~/.config/rclone/rclone.conf << EOF
[${R2_REMOTE_NAME}]
type = s3
provider = Cloudflare
access_key_id = ${R2_ACCESS_KEY_ID}
secret_access_key = ${R2_ACCESS_KEY_SECRET}
region = ${R2_REGION}
endpoint = ${R2_ENDPOINT}
acl = private
EOF

    # 测试连接
    log_info "测试rclone连接..."
    if rclone lsd ${R2_REMOTE_NAME}: &> /dev/null; then
        log_success "rclone配置成功,连接测试通过"
    else
        log_error "rclone配置失败,连接测试未通过"
        exit 1
    fi
}

# 全量备份函数
full_backup() {
    log_info "开始执行全量备份..."
    log_info "备份源: ${R2_REMOTE_NAME}:${R2_BUCKET_NAME}/ (整个存储桶)"
    log_info "备份目标目录: ${BACKUP_TARGET_DIR}"
    
    # 创建本地备份目录
    mkdir -p "${BACKUP_TARGET_DIR}"
    
    # 创建备份日志目录
    local log_dir="/var/log/r2_backup"
    sudo mkdir -p "$log_dir"
    local log_file="$log_dir/backup_$(date +%Y%m%d_%H%M%S).log"
    
    # 执行备份 - 备份整个存储桶,保持完整目录结构
    log_info "开始从Cloudflare R2同步整个存储桶到本地..."
    
    rclone sync "${R2_REMOTE_NAME}:${R2_BUCKET_NAME}/" "${BACKUP_TARGET_DIR}/" \
        --progress \
        --transfers 4 \
        --checkers 8 \
        --retries 3 \
        --low-level-retries 10 \
        --stats 30s \
        --log-file "$log_file" \
        --log-level INFO
    
    if [[ $? -eq 0 ]]; then
        log_success "全量备份完成"
        log_info "备份日志: $log_file"
        
        # 显示备份统计信息
        log_info "获取备份统计信息..."
        rclone size "${R2_REMOTE_NAME}:${R2_BUCKET_NAME}/${BACKUP_REMOTE_DIR}"
    else
        log_error "全量备份失败"
        log_error "请查看日志文件: $log_file"
        exit 1
    fi
}

# 显示菜单
show_menu() {
    echo
    echo "=================================="
    echo "  Cloudflare R2 数据备份工具"
    echo "  (从R2下载数据到本地服务器)"
    echo "=================================="
    echo "1. 全量备份 (从R2同步到本地)"
    echo "2. 查看备份状态"
    echo "3. 测试R2连接"
    echo "4. 删除R2目录"
    echo "5. 重新配置rclone"
    echo "0. 退出"
    echo "=================================="
}

# 查看备份列表
list_backups() {
    log_info "查看备份列表..."
    
    echo
    echo "=== 本地备份目录 ==="
    if [[ -d "${BACKUP_TARGET_DIR}" ]]; then
        ls -la "${BACKUP_TARGET_DIR}"
        echo
        echo "备份目录大小:"
        du -sh "${BACKUP_TARGET_DIR}"
    else
        echo "本地备份目录不存在: ${BACKUP_TARGET_DIR}"
    fi
    
    echo
    echo "=== R2存储桶内容 ==="
    rclone lsd "${R2_REMOTE_NAME}:${R2_BUCKET_NAME}" --max-depth 2
}

# 测试连接
test_connection() {
    log_info "测试Cloudflare R2连接..."
    if rclone lsd "${R2_REMOTE_NAME}:" &> /dev/null; then
        log_success "连接测试成功"
        rclone about "${R2_REMOTE_NAME}:"
    else
        log_error "连接测试失败"
    fi
}

# 删除R2存储桶中的指定顶层目录
delete_directory() {
    log_info "删除R2存储桶中的顶层目录..."
    
    echo
    echo "=== R2存储桶顶层目录列表 ==="
    
    # 获取顶层目录列表
    local dirs=$(rclone lsd "${R2_REMOTE_NAME}:${R2_BUCKET_NAME}" --max-depth 1 2>/dev/null | awk '{print $5}' | grep -v '^$')
    
    if [[ -z "$dirs" ]]; then
        log_warning "存储桶中没有找到任何目录"
        return 1
    fi
    
    # 显示目录列表
    local dir_array=()
    local index=1
    while IFS= read -r dir; do
        if [[ -n "$dir" ]]; then
            echo "$index. $dir"
            dir_array+=("$dir")
            ((index++))
        fi
    done <<< "$dirs"
    
    echo "0. 取消操作"
    echo
    
    # 用户选择
    read -p "请选择要删除的目录编号 [0-$((index-1))]: " choice
    
    # 验证输入
    if [[ ! "$choice" =~ ^[0-9]+$ ]] || [[ "$choice" -lt 0 ]] || [[ "$choice" -ge "$index" ]]; then
        log_error "无效的选择"
        return 1
    fi
    
    # 取消操作
    if [[ "$choice" -eq 0 ]]; then
        log_info "取消删除操作"
        return 0
    fi
    
    # 获取选择的目录
    local selected_dir="${dir_array[$((choice-1))]}"
    
    # 二次确认
    echo
    log_warning "警告:即将删除目录 '${selected_dir}' 及其所有内容"
    log_warning "此操作不可逆!"
    read -p "确认删除? 请输入 'DELETE' 来确认: " confirm
    
    if [[ "$confirm" != "DELETE" ]]; then
        log_info "取消删除操作"
        return 0
    fi
    
    # 执行删除
    log_info "正在删除目录: ${selected_dir}"
    
    if rclone purge "${R2_REMOTE_NAME}:${R2_BUCKET_NAME}/${selected_dir}" 2>/dev/null; then
        log_success "目录 '${selected_dir}' 删除成功"
    else
        log_error "目录 '${selected_dir}' 删除失败"
        return 1
    fi
}

# 主函数
main() {
    echo "Cloudflare R2备份脚本启动..."
    
    # 处理命令行参数 - 直接执行模式
    if [[ $# -gt 0 ]]; then
        # 检查并安装rclone
        if ! check_rclone; then
            install_rclone
        fi
        
        # 配置rclone
        configure_rclone
        
        case $1 in
            1)
                full_backup
                exit 0
                ;;
            2)
                list_backups
                exit 0
                ;;
            3)
                test_connection
                exit 0
                ;;
            4)
                delete_directory
                exit 0
                ;;
            5)
                configure_rclone
                exit 0
                ;;
            *)
                log_error "无效的参数: $1"
                echo "使用方法: $0 [1|2|3|4|5]"
                echo "1 - 全量备份"
                echo "2 - 查看备份列表"
                echo "3 - 测试连接"
                echo "4 - 删除R2目录"
                echo "5 - 重新配置rclone"
                exit 1
                ;;
        esac
    fi
    
    # 交互式菜单模式
    while true; do
        show_menu
        read -p "请选择操作 [0-4]: " choice
        
        case $choice in
            1)
                # 检查并安装rclone
                if ! check_rclone; then
                    install_rclone
                fi
                # 配置rclone
                configure_rclone
                full_backup
                ;;
            2)
                # 检查并安装rclone
                if ! check_rclone; then
                    install_rclone
                fi
                # 配置rclone
                configure_rclone
                list_backups
                ;;
            3)
                # 检查并安装rclone
                if ! check_rclone; then
                    install_rclone
                fi
                # 配置rclone
                configure_rclone
                test_connection
                ;;
            4)
                # 检查并安装rclone
                if ! check_rclone; then
                    install_rclone
                fi
                # 配置rclone
                configure_rclone
                delete_directory
                ;;
            5)
                # 检查并安装rclone
                if ! check_rclone; then
                    install_rclone
                fi
                configure_rclone
                ;;
            0)
                log_info "退出程序"
                exit 0
                ;;
            *)
                log_error "无效选择,请重新输入"
                ;;
        esac
        
        echo
        read -p "按回车键继续..." -r
    done
}

# 脚本入口
main "$@"

注意: 使用前请务必修改脚本中的 R2 配置参数,并确保访问密钥的安全性。