随机
Enter 搜索 ↑↓ 切换 Esc 清空

linux_sync_local

脚本

交互式的 Rsync 本地目录同步管理脚本,支持任务管理、正向 / 反向同步、批量执行、定时任务与权限修复。

linux_sync_local

交互式的 Rsync 本地目录同步管理脚本,支持任务管理、正向 / 反向同步、批量执行、定时任务与权限修复。

一键脚本

bash <(curl -sL gitee.com/meimolihan/linux-command_sh/raw/master/linux_sync_local.sh)

效果预览

执行脚本效果预览

脚本源码

#!/bin/bash
set -uo pipefail

gl_hui='\033[38;5;59m'
gl_hong='\033[38;5;9m'
gl_lv='\033[38;5;10m'
gl_huang='\033[38;5;11m'
gl_lan='\033[38;5;32m'
gl_bai='\033[38;5;15m'
gl_zi='\033[38;5;13m'
gl_bufan='\033[38;5;14m'

log_info()  { echo -e "${gl_lan}[信息]${gl_bai} $*"; }
log_ok()    { echo -e "${gl_lv}[成功]${gl_bai} $*"; }
log_warn()  { echo -e "${gl_huang}[警告]${gl_bai} $*"; }
log_error() { echo -e "${gl_hong}[错误]${gl_bai} $*" >&2; }

break_end() {
    echo -e "${gl_lv}操作完成${gl_bai}"
    echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
    read -r -n 1 -s -p ""
    echo ""
    clear
}

exit_script() {
    echo ""
    echo -ne "${gl_hong}感谢使用,再见!${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
    sleep_fractional 0.5
    echo -ne "${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
    sleep_fractional 0.6
    clear
    exit 0
}

sleep_fractional() {
    local seconds=$1
    if sleep "$seconds" 2>/dev/null; then return 0; fi
    if command -v perl >/dev/null 2>&1; then perl -e "select(undef, undef, undef, $seconds)"; return 0; fi
    if command -v python3 >/dev/null 2>&1; then python3 -c "import time; time.sleep($seconds)"; return 0; fi
    if command -v python >/dev/null 2>&1; then python -c "import time; time.sleep($seconds)"; return 0; fi
    local int_seconds=$(echo "$seconds" | awk '{print int($1+0.999)}')
    sleep "$int_seconds"
}

exit_animation() {
    echo -ne "\r${gl_lv}即将退出 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
    sleep_fractional 0.5
    echo -ne "${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
    sleep_fractional 0.6
    echo ""
}

cancel_return() {
    local menu_name="${1:-上一级选单}"
    echo -ne "${gl_lv}即将返回 ${gl_huang}${menu_name}${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
    sleep_fractional 0.5
    echo -ne "${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
    sleep_fractional 0.6
    echo ""
    clear
}

cancel_empty() {
    local menu_name="${1:-上一级选单}"
    echo -e "${gl_hong}空输入,返回 ${gl_huang}${menu_name}${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
    sleep_fractional 0.5
    echo -ne "${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
    sleep_fractional 0.6
    echo ""
    clear
}

install() {
    [[ $# -eq 0 ]] && {
        log_error "未提供软件包参数!"
        return 1
    }

    local pkg mgr ver cmd_ver pkg_ver installed=false
    for pkg in "$@"; do
        installed=false
        ver=""
        
        if command -v "$pkg" &>/dev/null; then
            cmd_ver=$("$pkg" --version 2>/dev/null | head -n1 | tr -cd '[:print:]' | grep -oE '[0-9]+(\.[0-9]+)+' | head -n1 || echo "")
            [[ -n "$cmd_ver" ]] && ver="$cmd_ver"
            installed=true
        fi
        
        if [[ "$pkg" == "7zip" || "$pkg" == "7z" ]]; then
            if command -v 7z &>/dev/null; then
                ver=$(7z 2>&1 | grep -oE '[0-9]+(\.[0-9]+)+' | head -n1 || echo "")
                [[ -n "$ver" ]] && installed=true
            fi
        fi
        
        if [[ "$installed" == false ]]; then
            if command -v opkg &>/dev/null; then
                if opkg list-installed | grep -q "^${pkg} "; then
                    installed=true
                    ver=$(opkg list-installed | grep "^${pkg} " | awk '{print $3}' 2>/dev/null || echo "")
                fi
            elif command -v dpkg-query &>/dev/null; then
                if dpkg-query -W -f='${Status}' "$pkg" 2>/dev/null | grep -q "install ok installed"; then
                    installed=true
                    ver=$(dpkg-query -W -f='${Version}' "$pkg" 2>/dev/null || echo "")
                fi
            elif command -v rpm &>/dev/null; then
                if rpm -q "$pkg" &>/dev/null; then
                    installed=true
                    ver=$(rpm -q --qf '%{VERSION}' "$pkg" 2>/dev/null || echo "")
                fi
            elif command -v apk &>/dev/null; then
                if apk info "$pkg" 2>/dev/null | grep -q "^installed"; then
                    installed=true
                    ver=$(apk info -a "$pkg" 2>/dev/null | grep -oE '[0-9]+(\.[0-9]+)+' | head -n1 || echo "")
                fi
            elif command -v pacman &>/dev/null; then
                if pacman -Qi "$pkg" &>/dev/null; then
                    installed=true
                    ver=$(pacman -Qi "$pkg" 2>/dev/null | grep -i "version" | grep -oE '[0-9]+(\.[0-9]+)+' | head -n1 || echo "")
                fi
            fi
        fi
        
        if [[ "$installed" == true ]]; then
            echo -e "${gl_huang}${pkg}${gl_bai} ${gl_lv}已安装${gl_bai}" \
                "$([[ -n "$ver" ]] && echo "版本 ${gl_lv}${ver}${gl_bai}")"
            continue
        fi
        
        echo -e ""
        echo -e "${gl_huang}开始安装:${gl_bai}${pkg}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        local install_success=false
        
        for mgr in opkg dnf yum apt apk pacman zypper pkg; do
            if ! command -v "$mgr" &>/dev/null; then
                continue
            fi
            
            case $mgr in
            opkg)
                echo -e "${gl_bai}使用包管理器: ${gl_zi}opkg (OpenWrt/iStoreOS)${gl_bai}"
                if [[ "$pkg" == "7zip" || "$pkg" == "7z" ]]; then
                    echo -e "${gl_bai}正在安装: ${gl_lv}p7zip${gl_bai}"
                    opkg update && opkg install p7zip && install_success=true
                else
                    opkg update && opkg install "$pkg" && install_success=true
                fi
                ;;
            dnf)
                echo -e "${gl_bai}使用包管理器: ${gl_zi}dnf (Fedora/RHEL)${gl_bai}"
                dnf -y update && dnf install -y "$pkg" && install_success=true
                ;;
            yum)
                echo -e "${gl_bai}使用包管理器: ${gl_zi}yum (CentOS/RHEL)${gl_bai}"
                yum -y update && yum install -y "$pkg" && install_success=true
                ;;
            apt)
                echo -e "${gl_bai}使用包管理器: ${gl_zi}apt (Debian/Ubuntu)${gl_bai}"
                apt update -y && apt install -y "$pkg" && install_success=true
                ;;
            apk)
                echo -e "${gl_bai}使用包管理器: ${gl_zi}apk (Alpine)${gl_bai}"
                apk update && apk add "$pkg" && install_success=true
                ;;
            pacman)
                echo -e "${gl_bai}使用包管理器: ${gl_zi}pacman (Arch/Manjaro)${gl_bai}"
                pacman -Syu --noconfirm && pacman -S --noconfirm "$pkg" && install_success=true
                ;;
            zypper)
                echo -e "${gl_bai}使用包管理器: ${gl_zi}zypper (openSUSE)${gl_bai}"
                zypper refresh && zypper install -y "$pkg" && install_success=true
                ;;
            pkg)
                echo -e "${gl_bai}使用包管理器: ${gl_zi}pkg (FreeBSD)${gl_bai}"
                pkg update && pkg install -y "$pkg" && install_success=true
                ;;
            esac
            [[ "$install_success" == true ]] && break
        done
        if [[ "$install_success" == true ]]; then
            echo -e "${gl_lv}${pkg} 安装成功${gl_bai}"
        else
            echo -e "${gl_hong}${pkg} 安装失败${gl_bai}"
        fi
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    done
}

edit_crontab() {
    clear
    echo -e "${gl_zi}>>> 编辑cron文件${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    if ! command -v crontab &>/dev/null; then
        log_error "crontab命令不存在,请检查系统"
        exit_animation
        return 1
    fi

    echo -e "${gl_bai}正在打开${gl_lv}crontab${gl_bai}编辑器${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    log_warn "请谨慎编辑,保存后更改将立即生效"

    if crontab -e; then
        log_ok "crontab编辑完成"
    else
        log_error "crontab编辑失败"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

list_color_init() {
    export gl_hui=$'\033[38;5;59m'
    export gl_hong=$'\033[38;5;9m'
    export gl_lv=$'\033[38;5;10m'
    export gl_huang=$'\033[38;5;11m'
    export gl_lan=$'\033[38;5;32m'
    export gl_bai=$'\033[38;5;15m'
    export gl_zi=$'\033[38;5;13m'
    export gl_bufan=$'\033[38;5;14m'
    export reset=$'\033[0m'
}
list_color_init

column_if_available() {
    if command -v column &> /dev/null; then
        column -t -s $'\t'
    else
        cat
    fi
}

list_beautify_linux_crontab() {
    {
        printf "%s%-12s\t%-8s\t%-8s\t%-8s\t%-12s\t%-40s%s\n" \
            "$gl_hui" "分钟" "小时" "日期" "月份" "星期" "执行命令" "$reset"
        printf "%s%-12s\t%-8s\t%-8s\t%-8s\t%-12s\t%-40s%s\n" \
            "$gl_hui" "------------" "--------" "--------" "--------" "------------" "----------------------------------------" "$reset"

        crontab -l 2>/dev/null | grep -v '^#' | awk NF | \
            awk -v green="$gl_lv" -v yellow="$gl_huang" \
                -v blue="$gl_lan" -v reset="$reset" '
        BEGIN {OFS="\t"}
        {
            if ($1 ~ /^@/) {
                minute = $1
                hour = ""
                day = ""
                month = ""
                week = ""
                cmd = substr($0, index($0, $2))
            } else {
                minute = $1
                hour = $2
                day = $3
                month = $4
                week = $5
                cmd = substr($0, index($0, $6))
            }
            printf "%s%-12s%s\t%s%-8s%s\t%s%-8s%s\t%s%-8s%s\t%s%-12s%s\t%s%-40s%s\n",
                blue, minute, reset,
                yellow, hour, reset,
                blue, day, reset,
                yellow, month, reset,
                blue, week, reset,
                green, cmd, reset
        }'
    } | column_if_available
}

list_beautify_all() {
    clear
    echo -e "${gl_zi}>>> Linux定时任务列表${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    list_beautify_linux_crontab
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

local_init_globals() {
    LOCAL_SYNC_CONFIG="$HOME/.local_rsync_tasks"

    mkdir -p "$(dirname "$LOCAL_SYNC_CONFIG")" 2>/dev/null || {
        echo -e "${gl_hong}错误: 无法创建配置目录${gl_bai}"
        return 1
    }
    return 0
}

local_list_tasks() {
    local_init_globals || return 1

    echo "已保存的本地同步任务:"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    if [[ -f "$LOCAL_SYNC_CONFIG" ]] && [[ -s "$LOCAL_SYNC_CONFIG" ]]; then
        local line_num=1
        while IFS='|' read -r name source target options; do
            printf "${gl_bufan}%3d. ${gl_bai}- ${gl_zi}%-10s${gl_bai} ( ${gl_huang}%s${gl_bai} -> ${gl_lv}%s${gl_bai} )\n" \
                "$line_num" "$name" "$source" "$target"
            ((line_num++))
        done <"$LOCAL_SYNC_CONFIG"
    else
        echo -e "${gl_huang}暂无同步任务${gl_bai}"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
}

local_add_task() {
    local_init_globals || return 1

    echo "创建新本地同步任务示例:"
    echo -e "  ${gl_bai}- 任务名称: ${gl_huang}backup_www${gl_bai}"
    echo -e "  ${gl_bai}- 源目录: ${gl_huang}/var/www${gl_bai}"
    echo -e "  ${gl_bai}- 目标目录: ${gl_huang}/backup/www${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local name source_path target_path options

    while true; do
        read -r -e -p "$(echo -e "${gl_bai}请输入任务名称(${gl_huang}0${gl_bai})返回: ")" name
        [ "$name" = "0" ] && { cancel_return "上一级选单"; return 1; }
        if [[ -z "$name" ]]; then
            echo -e "${gl_hong}错误: 任务名称不能为空${gl_bai}"
            continue
        fi
        
        if [[ -f "$LOCAL_SYNC_CONFIG" ]] && grep -q "^$name|" "$LOCAL_SYNC_CONFIG"; then
            echo -e "${gl_hong}错误: 任务名称已存在,请重新输入${gl_bai}"
            continue
        fi
        break
    done

    while true; do
        read -r -e -p "请输入源目录: " source_path
        if [[ -z "$source_path" ]]; then
            echo -e "${gl_hong}错误: 源目录不能为空${gl_bai}"
            continue
        fi
        
        if [[ ! -d "$source_path" ]]; then
            echo -e "${gl_huang}警告: 源目录不存在,请确认路径是否正确${gl_bai}"
            read -r -e -p "是否继续创建任务? (y/n): " confirm
            if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
                continue
            fi
        fi
        break
    done

    while true; do
        read -r -e -p "请输入目标目录: " target_path
        if [[ -z "$target_path" ]]; then
            echo -e "${gl_hong}错误: 目标目录不能为空${gl_bai}"
            continue
        fi
        break
    done

    source_path="${source_path%/}/"
    target_path="${target_path%/}/"

    echo ""
    echo -e "${gl_huang}>>> 请选择同步模式"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bufan}1. ${gl_bai}标准模式 (-avhz --progress) - 增量同步,保留文件属性"
    echo -e "${gl_bufan}2. ${gl_bai}安全模式 (-avhz --progress --delete-delay) - 删除目标中多余文件"
    echo -e "${gl_bufan}3. ${gl_bai}严格模式 (-avhz --progress --delete --checksum) - 校验文件内容"
    echo -e "${gl_bufan}4. ${gl_bai}快速模式 (-avh) - 基本同步,不压缩"
    echo -e "${gl_bufan}5. ${gl_bai}权限友好模式 (-avh --no-perms --no-owner --no-group) - 忽略权限问题"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -r -e -p "请输入你的选择: " mode

    case $mode in
    1) options="-avhz --progress" ;;
    2) options="-avhz --progress --delete-delay" ;;
    3) options="-avhz --progress --delete --checksum" ;;
    4) options="-avh" ;;
    5) options="-avh --no-perms --no-owner --no-group" ;;
    *)
        echo "无效选择,使用标准模式 -avhz --progress"
        options="-avhz --progress"
        ;;
    esac

    echo ""
    echo -e "${gl_huang}>>> 高级选项"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bufan}1. ${gl_bai}限速同步 (避免影响系统性能)"
    echo -e "${gl_bufan}2. ${gl_bai}排除特定文件类型"
    echo -e "${gl_bufan}3. ${gl_bai}排除Windows系统目录 (解决权限问题)"
    echo -e "${gl_bufan}4. ${gl_bai}跳过高级选项"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -r -e -p "请输入你的选择: " advanced_opt

    case $advanced_opt in
    1)
        read -r -e -p "请输入限速值 (单位: KB/s): " speed_limit
        if [[ "$speed_limit" =~ ^[0-9]+$ ]]; then
            options="$options --bwlimit=$speed_limit"
            echo -e "${gl_lv}已设置限速: ${speed_limit}KB/s${gl_bai}"
        else
            echo -e "${gl_hong}无效的限速值,跳过限速设置${gl_bai}"
        fi
        ;;
    2)
        read -r -e -p "请输入要排除的文件模式 (如: *.tmp,*.log): " exclude_patterns
        if [[ -n "$exclude_patterns" ]]; then
            options="$options --exclude='$exclude_patterns'"
            echo -e "${gl_lv}已设置排除模式: $exclude_patterns${gl_bai}"
        fi
        ;;
    3)
        options="$options --exclude='\$RECYCLE.BIN/' --exclude='System Volume Information/' --exclude='Thumbs.db' --exclude='Desktop.ini'"
        echo -e "${gl_lv}已排除Windows系统目录,解决权限问题${gl_bai}"
        ;;
    4 | "")
        echo "跳过高级选项"
        ;;
    *)
        echo -e "${gl_hong}无效选择,跳过高级选项${gl_bai}"
        ;;
    esac

    echo "$name|$source_path|$target_path|$options" >>"$LOCAL_SYNC_CONFIG"
    echo -e "${gl_lv}✓ 本地同步任务 '${name}' 已保存!${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}任务详情:${gl_bai}"
    echo -e "  ${gl_bai}名称: ${gl_huang}${name}${gl_bai}"
    echo -e "  ${gl_bai}源目录: ${gl_huang}${source_path}${gl_bai}"
    echo -e "  ${gl_bai}目标目录: ${gl_lv}${target_path}${gl_bai}"
    echo -e "  ${gl_bai}同步选项: ${gl_zi}${options}${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

local_delete_task() {
    local_init_globals || return 1

    if [[ ! -f "$LOCAL_SYNC_CONFIG" ]] || [[ ! -s "$LOCAL_SYNC_CONFIG" ]]; then
        echo -e "${gl_hong}错误: 暂无同步任务可删除${gl_bai}"
        exit_animation
        return 1
    fi

    echo ""

    local_list_tasks

    echo ""
    echo -e "${gl_huang}>>> 删除本地同步任务${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    local num
    read -r -e -p "$(echo -e "${gl_bai}请输入要删除的任务编号(${gl_huang}0${gl_bai}返回): ")" num

    [ "$num" = "0" ] && { cancel_return "Rsync本地同步工具"; return 1; }

    if ! [[ "$num" =~ ^[0-9]+$ ]]; then
        echo -e "${gl_hong}错误: 请输入有效的数字编号${gl_bai}"
        exit_animation
        return 1
    fi

    local total_tasks
    total_tasks=$(wc -l <"$LOCAL_SYNC_CONFIG" 2>/dev/null)
    if [[ "$num" -lt 1 || "$num" -gt "$total_tasks" ]]; then
        echo -e "${gl_hong}错误: 任务编号不存在${gl_bai}"
        exit_animation
        return 1
    fi

    local task_line
    task_line=$(sed -n "${num}p" "$LOCAL_SYNC_CONFIG")
    local task_name source_path target_path options
    IFS='|' read -r task_name source_path target_path options <<<"$task_line"

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}即将删除的任务:${gl_bai}"
    echo -e "  名称: ${gl_huang}${task_name}${gl_bai}"
    echo -e "  源目录: ${gl_huang}${source_path}${gl_bai}"
    echo -e "  目标目录: ${gl_lv}${target_path}${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    read -r -e -p "$(echo -e "${gl_bai}确定要删除这个任务吗? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
    if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
        local temp_file
        temp_file=$(mktemp)
        sed "${num}d" "$LOCAL_SYNC_CONFIG" >"$temp_file"
        if mv "$temp_file" "$LOCAL_SYNC_CONFIG" 2>/dev/null; then
            echo -e "${gl_lv}✓ 任务已删除!${gl_bai}"
        else
            echo -e "${gl_hong}错误: 删除任务失败${gl_bai}"
            rm -f "$temp_file"
            return 1
        fi
    else
        echo "取消删除"
    fi

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

local_run_task() {
    local_init_globals || return 1

    if [[ ! -f "$LOCAL_SYNC_CONFIG" ]] || [[ ! -s "$LOCAL_SYNC_CONFIG" ]]; then
        echo -e "${gl_hong}错误: 暂无同步任务可执行${gl_bai}"
        return 1
    fi

    local num="$1"

    if [[ -z "$num" ]]; then
        local_list_tasks
        read -r -e -p "请输入要执行的任务编号: " num
    fi

    if ! [[ "$num" =~ ^[0-9]+$ ]]; then
        echo -e "${gl_hong}错误: 请输入有效的数字编号${gl_bai}"
        exit_animation
        return 1
    fi

    local total_tasks
    total_tasks=$(wc -l <"$LOCAL_SYNC_CONFIG" 2>/dev/null)
    if [[ "$num" -lt 1 || "$num" -gt "$total_tasks" ]]; then
        echo -e "${gl_hong}错误: 任务编号不存在${gl_bai}"
        exit_animation
        return 1
    fi

    local task
    task=$(sed -n "${num}p" "$LOCAL_SYNC_CONFIG")
    local name source_path target_path options
    IFS='|' read -r name source_path target_path options <<<"$task"

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}开始执行本地同步任务: ${gl_huang}${name}${gl_bai}"
    echo -e "${gl_bai}同步方向: ${gl_huang}${source_path} ${gl_hong}-> ${gl_lv}${target_path}${gl_bai}"
    echo -e "${gl_bai}同步选项: ${gl_zi}${options}${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    if [[ ! -d "$source_path" ]]; then
        echo -e "${gl_hong}错误: 源目录不存在!${gl_bai}"
        echo -e "${gl_hong}请检查路径: ${source_path}${gl_bai}"
        exit_animation
        return 1
    fi

    if [[ ! -r "$source_path" ]]; then
        echo -e "${gl_huang}警告: 源目录读取权限受限${gl_bai}"
        echo -e "${gl_huang}建议: 使用权限友好模式同步${gl_bai}"
    fi

    if [[ ! -d "$target_path" ]]; then
        echo -e "${gl_huang}目标目录不存在,正在自动创建: ${gl_lv}${target_path}${gl_bai}"
        if mkdir -p "$target_path" 2>/dev/null; then
            echo -e "${gl_lv}✓ 目标目录已创建${gl_bai}"
        else
            echo -e "${gl_hong}错误: 无法创建目标目录${gl_bai}"
            exit_animation
            return 1
        fi
    fi

    if [[ ! -w "$target_path" ]]; then
        echo -e "${gl_hong}错误: 目标目录写入权限不足!${gl_bai}"
        echo -e "${gl_huang}请检查目录权限或使用sudo执行${gl_bai}"
        exit_animation
        return 1
    fi

    local start_time
    start_time=$(date +%s)
    echo -e "${gl_bai}开始时间: ${gl_lv}$(date)${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}正在执行同步${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo -e "${gl_bai}详细输出如下:${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    local output_file
    output_file=$(mktemp)
    local sync_result
    local error_count=0
    eval rsync $options "$source_path" "$target_path" 2>&1 | tee "$output_file"
    sync_result=${PIPESTATUS[0]}
    error_count=$(grep -c "Permission denied\|rsync error\|failed" "$output_file" || echo 0)
    rm -f "$output_file"
    local end_time duration
    end_time=$(date +%s)
    duration=$((end_time - start_time))

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    if [[ $sync_result -eq 0 ]]; then
        echo -e "${gl_lv}✓ 本地同步完成!${gl_bai}"
        echo -e "${gl_bai}同步统计:${gl_bai}"
        echo -e "  - 任务名称: ${gl_huang}${name}${gl_bai}"
        echo -e "  - 源目录: ${gl_huang}${source_path}${gl_bai}"
        echo -e "  - 目标目录: ${gl_lv}${target_path}${gl_bai}"
        echo -e "  - 耗时: ${gl_zi}${duration}${gl_bai}"
        echo -e "  - 完成时间: ${gl_lv}$(date)${gl_bai}"
        echo -e "  - 同步结果: ${gl_lv}成功${gl_bai}"
    elif [[ $sync_result -eq 23 ]] && [[ $error_count -gt 0 ]]; then
        echo -e "${gl_huang}⚠ 同步部分完成,但有文件权限问题${gl_bai}"
        echo -e "${gl_bai}同步统计:${gl_bai}"
        echo -e "  - 任务名称: ${gl_huang}${name}${gl_bai}"
        echo -e "  - 源目录: ${gl_huang}${source_path}${gl_bai}"
        echo -e "  - 目标目录: ${gl_lv}${target_path}${gl_bai}"
        echo -e "  - 耗时: ${gl_zi}${duration}${gl_bai}"
        echo -e "  - 完成时间: ${gl_lv}$(date)${gl_bai}"
        echo -e "  - 同步结果: ${gl_huang}部分成功${gl_bai}"
        echo -e "  - 错误类型: 文件权限受限"
        echo -e "${gl_huang}建议解决方案:${gl_bai}"
        echo -e "  ${gl_bufan}1. ${gl_bai}重新编辑任务,选择'权限友好模式'"
        echo -e "  ${gl_bufan}2. ${gl_bai}在高级选项中选择'排除Windows系统目录'"
        echo -e "  ${gl_bufan}3. ${gl_bai}使用root权限执行: sudo m local_rsync_run $num"
    else
        echo -e "${gl_hong}✗ 同步失败! 错误代码: ${sync_result}${gl_bai}"
        echo -e "${gl_hong}可能的原因:${gl_bai}"
        echo -e "  ${gl_bufan}1. ${gl_bai}目标目录权限不足 - 使用sudo或检查目录权限"
        echo -e "  ${gl_bufan}2. ${gl_bai}磁盘空间不足 - 检查目标磁盘空间"
        echo -e "  ${gl_bufan}3. ${gl_bai}文件被占用或权限问题 - 尝试重新编辑任务选择权限友好模式"
        echo -e "  ${gl_bufan}4. ${gl_bai}网络存储连接问题(如果是网络路径)"
        echo -e "  ${gl_bufan}5. ${gl_bai}rsync选项配置错误 - 检查同步选项"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
    return $sync_result
}

local_run_all_tasks() {
    local_init_globals || return 1

    if [[ ! -f "$LOCAL_SYNC_CONFIG" ]] || [[ ! -s "$LOCAL_SYNC_CONFIG" ]]; then
        echo -e "${gl_hong}错误: 暂无同步任务可执行${gl_bai}"
        exit_animation
        return 1
    fi

    local total_tasks
    total_tasks=$(wc -l <"$LOCAL_SYNC_CONFIG")
    echo -e ""
    echo -e "${gl_bai}开始批量执行 ${gl_huang}${total_tasks} ${gl_bai}个本地同步任务${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local success_count=0
    local fail_count=0
    local partial_count=0
    local current_task=0

    while IFS= read -r task; do
        ((current_task++))
        local name source_path target_path options
        IFS='|' read -r name source_path target_path options <<<"$task"

        echo -e "${gl_bai}[${gl_lv}${current_task}${gl_bai}/${gl_huang}${total_tasks}${gl_bai}] 执行任务: ${gl_huang}${name}${gl_bai}"
        echo -e "${gl_bai}路径: ${gl_huang}${source_path} ${gl_bai}-> ${gl_lv}${target_path}${gl_bai}"

        if [[ ! -d "$source_path" ]]; then
            echo -e "${gl_hong}✗ 失败: 源目录不存在${gl_bai}"
            ((fail_count++))
            echo ""
            continue
        fi

        local output_file
        output_file=$(mktemp)
        eval rsync $options "$source_path" "$target_path" >"$output_file" 2>&1
        local sync_result=$?

        if [[ $sync_result -eq 0 ]]; then
            echo -e "${gl_lv}✓ 成功${gl_bai}"
            ((success_count++))
        elif [[ $sync_result -eq 23 ]] && grep -q "Permission denied" "$output_file"; then
            echo -e "${gl_huang}⚠ 部分成功 (权限问题)${gl_bai}"
            ((partial_count++))
        else
            echo -e "${gl_hong}✗ 失败 (错误代码: $sync_result)${gl_bai}"
            ((fail_count++))
        fi

        rm -f "$output_file"
        echo ""
    done <"$LOCAL_SYNC_CONFIG"

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}批量执行完成:"
    echo -e "  ${gl_lv}✓ 成功: ${success_count}${gl_bai}"
    echo -e "  ${gl_huang}⚠ 部分成功: ${partial_count}${gl_bai}"
    echo -e "  ${gl_hong}✗ 失败: ${fail_count}${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end

    if [[ $fail_count -eq 0 ]] && [[ $partial_count -eq 0 ]]; then
        return 0
    elif [[ $fail_count -gt 0 ]]; then
        return 1
    else
        return 2
    fi
}

local_schedule_task() {
    echo ""
    echo -e "${gl_zi}>>> 创建本地定时任务${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    local_init_globals || return 1

    if [[ ! -f "$LOCAL_SYNC_CONFIG" ]] || [[ ! -s "$LOCAL_SYNC_CONFIG" ]]; then
        echo -e "${gl_hong}错误: 暂无同步任务可设置定时${gl_bai}"
        exit_animation
        return 1
    fi

    local num

    read -r -e -p "$(echo -e "${gl_bai}请输入要定时同步的任务编号(${gl_huang}0${gl_bai}返回): ")" num

    [ "$num" = "0" ] && { cancel_return "Rsync本地同步工具"; return 1; }
    [ -z "$num" ] && { cancel_empty "上一级选单"; return 1; }

    if ! [[ "$num" =~ ^[0-9]+$ ]]; then
        echo -e "${gl_hong}错误: 请输入有效的数字编号${gl_bai}"
        exit_animation
        return 1
    fi

    local total_tasks
    total_tasks=$(wc -l <"$LOCAL_SYNC_CONFIG")
    if [[ "$num" -lt 1 || "$num" -gt "$total_tasks" ]]; then
        echo -e "${gl_hong}错误: 任务编号不存在${gl_bai}"
        exit_animation
        return 1
    fi

    local task
    task=$(sed -n "${num}p" "$LOCAL_SYNC_CONFIG")
    local name source_path target_path options
    IFS='|' read -r name source_path target_path options <<<"$task"

    echo ""
    echo -e "${gl_huang}>>> 请选择定时执行间隔${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bufan}1. ${gl_bai}每小时执行一次"
    echo -e "${gl_bufan}2. ${gl_bai}每天执行一次"
    echo -e "${gl_bufan}3. ${gl_bai}每周执行一次"
    echo -e "${gl_bufan}4. ${gl_bai}每月执行一次"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -r -e -p "请输入你的选择: " interval

    local random_minute
    random_minute=$(shuf -i 0-59 -n 1)
    local cron_time=""
    local interval_desc=""

    case "$interval" in
    1)
        cron_time="$random_minute * * * *"
        interval_desc="每小时(随机分钟 $random_minute)"
        ;;
    2)
        cron_time="$random_minute 2 * * *"
        interval_desc="每天凌晨2点(随机分钟 $random_minute)"
        ;;
    3)
        cron_time="$random_minute 3 * * 1"
        interval_desc="每周一凌晨3点(随机分钟 $random_minute)"
        ;;
    4)
        cron_time="$random_minute 4 1 * *"
        interval_desc="每月1号凌晨4点(随机分钟 $random_minute)"
        ;;
    *)
        echo -e "${gl_hong}错误: 请输入有效的选项!${gl_bai}"
        return 1
        ;;
    esac

    local script_path
    script_path="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")"

    local cron_job
    cron_job="$cron_time m local_rsync_run $num"

    local cron_service_active=false
    if command -v systemctl >/dev/null 2>&1; then
        if systemctl is-active cron >/dev/null 2>&1 || systemctl is-active crond >/dev/null 2>&1; then
            cron_service_active=true
        fi
    elif command -v service >/dev/null 2>&1; then
        if service cron status >/dev/null 2>&1 || service crond status >/dev/null 2>&1; then
            cron_service_active=true
        fi
    fi

    if ! $cron_service_active; then
        echo -e "${gl_huang}警告: cron服务未运行,正在尝试启动${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
        if command -v systemctl >/dev/null 2>&1; then
            sudo systemctl start cron 2>/dev/null || sudo systemctl start crond 2>/dev/null
        elif command -v service >/dev/null 2>&1; then
            sudo service cron start 2>/dev/null || sudo service crond start 2>/dev/null
        fi
    fi

    if crontab -l 2>/dev/null | grep -q "local_rsync_run $num"; then
        echo -e "${gl_hong}错误: 该任务的定时同步已存在!${gl_bai}"
        return 1
    fi

    (
        crontab -l 2>/dev/null | grep -v "^#"
        echo "# 本地Rsync定时任务: $name"
        echo "$cron_job"
        echo ""
    ) | crontab -

    echo ""
    echo -e "${gl_lv}✓ 定时任务已创建:${gl_huang}$cron_job${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}任务详情:${gl_bai}"
    echo -e "  - 任务名称: ${gl_huang}${name}${gl_bai}"
    echo -e "  - 执行间隔: ${gl_huang}${interval_desc}${gl_bai}"
    echo -e "  - 源目录: ${gl_huang}${source_path}${gl_bai}"
    echo -e "  - 目标目录: ${gl_lv}${target_path}${gl_bai}"
    echo -e "  - 同步选项: ${gl_zi}${options}${gl_bai}"
    echo -e "  - Cron命令: ${gl_zi}$cron_job${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}当前cron状态:${gl_bai}"
    if $cron_service_active; then
        echo -e "  ${gl_lv}✓ cron服务运行正常${gl_bai}"
    else
        echo -e "  ${gl_huang}⚠ cron服务未运行,定时任务可能无法执行${gl_bai}"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

local_view_schedules() {
    echo "当前的本地同步定时任务:"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    local cron_active=false
    if command -v systemctl >/dev/null 2>&1; then
        if systemctl is-active cron >/dev/null 2>&1 || systemctl is-active crond >/dev/null 2>&1; then
            cron_active=true
        fi
    elif command -v service >/dev/null 2>&1; then
        if service cron status >/dev/null 2>&1 || service crond status >/dev/null 2>&1; then
            cron_active=true
        fi
    fi

    if ! $cron_active; then
        echo -e "${gl_huang}警告: cron服务未运行,定时任务可能无法执行${gl_bai}"
        echo -e "${gl_huang}启动命令: sudo systemctl start cron${gl_bai}"
    fi

    local crontab_content
    crontab_content=$(crontab -l 2>/dev/null)

    if [[ $? -ne 0 ]] || [[ -z "$crontab_content" ]]; then
        echo -e "${gl_huang}当前用户暂无定时任务${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        return 0
    fi

    local task_count=0
    while IFS= read -r line; do
        [[ -z "$line" ]] && continue
        [[ "$line" =~ ^# ]] && continue

        if [[ "$line" =~ local_rsync_run ]] || [[ "$line" =~ local_rsync_run ]]; then
            ((task_count++))
            local task_num
            task_num=$(echo "$line" | grep -o -- "local_rsync_run [0-9]\+" | awk '{print $2}' ||
                echo "$line" | grep -o "local_rsync_run [0-9]\+" | awk '{print $2}')

            local task_name=""
            local source_path=""
            local target_path=""
            local options=""
            if [[ -n "$task_num" ]] && [[ -f "$LOCAL_SYNC_CONFIG" ]]; then
                local task_line
                task_line=$(sed -n "${task_num}p" "$LOCAL_SYNC_CONFIG" 2>/dev/null)
                if [[ -n "$task_line" ]]; then
                    IFS='|' read -r task_name source_path target_path options <<<"$task_line"
                fi
            fi

            echo -e "${gl_bufan}${task_count}. ${gl_bai}Cron表达式: ${gl_zi}${line}${gl_bai}"
            if [[ -n "$task_name" ]]; then
                echo -e "   任务名称: ${gl_huang}${task_name}${gl_bai}"
                echo -e "   源目录:   ${gl_huang}${source_path}${gl_bai}"
                echo -e "   目标目录: ${gl_lv}${target_path}${gl_bai}"
                echo -e "   同步选项: ${gl_zi}${options}${gl_bai}"
            else
                echo -e "   ${gl_hong}警告: 无法获取任务详细信息(可能对应的同步任务已被删除)${gl_bai}"
            fi
            echo ""
        fi
    done <<<"$crontab_content"

    if [[ $task_count -eq 0 ]]; then
        echo -e "${gl_huang}暂无本地同步定时任务${gl_bai}"
    else
        echo -e "${gl_bai}共找到 ${gl_huang}${task_count} ${gl_bai}个定时任务${gl_bai}"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
}

local_delete_schedule() {
    clear
    echo ""
    echo -e "${gl_zi}>>> 删除定时任务${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    local_view_schedules

    local task_num

    read -r -e -p "$(echo -e "${gl_bai}请输入要删除的定时任务编号(${gl_huang}0${gl_bai}返回): ")" task_num

    [ "$task_num" = "0" ] && { cancel_return "Rsync本地同步工具"; return 1; }
    [ -z "$task_num" ] && { cancel_empty "上一级选单"; return 1; }

    if ! [[ "$task_num" =~ ^[0-9]+$ ]]; then
        echo -e "${gl_hong}错误: 请输入有效的数字编号${gl_bai}"
        exit_animation    # 即将退出动画
        return 1
    fi

    local crontab_content
    crontab_content=$(crontab -l 2>/dev/null)

    if [[ $? -ne 0 ]] || [[ -z "$crontab_content" ]]; then
        echo -e "${gl_hong}错误: 未找到定时任务${gl_bai}"
        exit_animation
        return 1
    fi

    local current_task=0
    local target_line=""
    local target_comment_line=""
    local found_target=false
    local prev_line=""
    
    while IFS= read -r line; do
        if [[ "$line" =~ local_rsync_run ]] || [[ "$line" =~ local_rsync_run ]]; then
            ((current_task++))
            if [[ $current_task -eq $task_num ]]; then
                target_line="$line"
                found_target=true
                
                if [[ -n "$prev_line" ]] && [[ "$prev_line" =~ ^#.*本地Rsync定时任务 ]]; then
                    target_comment_line="$prev_line"
                fi
                break
            fi
        fi
        prev_line="$line"
    done <<<"$crontab_content"

    if [[ -z "$target_line" ]]; then
        echo -e "${gl_hong}错误: 未找到该编号的定时任务${gl_bai}"
        exit_animation
        return 1
    fi

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}即将删除的任务:${gl_bai}"
    if [[ -n "$target_comment_line" ]]; then
        echo -e "${gl_huang}注释行: $target_comment_line${gl_bai}"
    fi
    echo -e "${gl_huang}任务行: $target_line${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    read -r -e -p "$(echo -e "${gl_bai}确定要删除这个定时任务吗? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
    if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
        local temp_file
        temp_file=$(mktemp)
        
        crontab -l 2>/dev/null > "$temp_file"
        
        if [[ -n "$target_comment_line" ]]; then
            local temp_file2
            temp_file2=$(mktemp)
            grep -vF "$target_comment_line" "$temp_file" > "$temp_file2"
            mv "$temp_file2" "$temp_file"
        fi
        
        local temp_file3
        temp_file3=$(mktemp)
        grep -vF "$target_line" "$temp_file" > "$temp_file3"
        mv "$temp_file3" "$temp_file"

        if grep -qF "$target_line" "$temp_file"; then
            echo -e "${gl_hong}错误: 删除任务失败${gl_bai}"
        else
            crontab "$temp_file"
            echo -e "${gl_lv}✓ 定时任务已删除!${gl_bai}"
            
            if crontab -l 2>/dev/null | grep -qF "$target_line"; then
                echo -e "${gl_huang}警告: 定时任务可能未被完全删除${gl_bai}"
            fi
        fi

        rm -f "$temp_file"
    else
        echo "取消删除"
    fi

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

local_run_task_reverse() {
    local_init_globals || return 1

    if [[ ! -f "$LOCAL_SYNC_CONFIG" ]] || [[ ! -s "$LOCAL_SYNC_CONFIG" ]]; then
        echo -e "${gl_hong}错误: 暂无同步任务可执行${gl_bai}"
        exit_animation
        return 1
    fi

    local num="$1"

    if [[ -z "$num" ]]; then
        local_list_tasks
        read -r -e -p "请输入要执行反向同步的任务编号: " num
    fi

    if ! [[ "$num" =~ ^[0-9]+$ ]]; then
        echo -e "${gl_hong}错误: 请输入有效的数字编号${gl_bai}"
        exit_animation
        return 1
    fi

    local total_tasks
    total_tasks=$(wc -l <"$LOCAL_SYNC_CONFIG" 2>/dev/null)
    if [[ "$num" -lt 1 || "$num" -gt "$total_tasks" ]]; then
        echo -e "${gl_hong}错误: 任务编号不存在${gl_bai}"
        exit_animation
        return 1
    fi

    local task
    task=$(sed -n "${num}p" "$LOCAL_SYNC_CONFIG")
    local name source_path target_path options
    IFS='|' read -r name source_path target_path options <<<"$task"

    echo -e "${gl_hong}⚠⚠⚠ 警告:反向同步 ⚠⚠⚠${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}原始任务方向: ${gl_huang}${source_path} ${gl_bai}-> ${gl_lv}${target_path}${gl_bai}"
    echo -e "${gl_bai}反向同步方向: ${gl_hong}${target_path} ${gl_bai}-> ${gl_huang}${source_path}${gl_bai}"
    echo -e ""
    echo -e "${gl_hong}注意:此操作会将目标目录的内容同步回源目录,可能会覆盖源文件!${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -r -e -p "$(echo -e "${gl_bai}确认执行反向同步吗? (${gl_hong}输入 ${gl_huang}y ${gl_hong}确认${gl_bai}/${gl_lv}任意键取消${gl_bai}): ")" confirm
    if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
        echo -e "${gl_huang}已取消反向同步操作${gl_bai}"
        return 0
    fi

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}开始执行本地反向同步任务: ${gl_hong}${name}${gl_bai}"
    echo -e "${gl_bai}同步方向: ${gl_lv}${target_path} ${gl_hong}-> ${gl_huang}${source_path}${gl_bai}"
    echo -e "${gl_bai}同步选项: ${gl_zi}${options}${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    if [[ ! -d "$target_path" ]]; then
        echo -e "${gl_hong}错误: 原目标目录(现源目录)不存在!${gl_bai}"
        echo -e "${gl_hong}请检查路径: ${target_path}${gl_bai}"
        exit_animation
        return 1
    fi

    if [[ ! -d "$source_path" ]]; then
        echo -e "${gl_huang}警告: 原源目录(现目标目录)不存在,正在自动创建: ${gl_huang}${source_path}${gl_bai}"
        if mkdir -p "$source_path" 2>/dev/null; then
            echo -e "${gl_lv}✓ 目录已创建${gl_bai}"
        else
            echo -e "${gl_hong}错误: 无法创建目录${gl_bai}"
            exit_animation
            return 1
        fi
    fi

    if [[ ! -w "$source_path" ]]; then
        echo -e "${gl_hong}错误: 原源目录(现目标目录)写入权限不足!${gl_bai}"
        echo -e "${gl_huang}请检查目录权限或使用sudo执行${gl_bai}"
        exit_animation
        return 1
    fi

    local start_time
    start_time=$(date +%s)
    echo -e "${gl_bai}开始时间: ${gl_lv}$(date)${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}正在执行反向同步${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo -e "${gl_bai}详细输出如下:${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local output_file
    output_file=$(mktemp)
    local sync_result
    local error_count=0

    eval rsync $options "$target_path" "$source_path" 2>&1 | tee "$output_file"
    sync_result=${PIPESTATUS[0]}

    error_count=$(grep -c "Permission denied\|rsync error\|failed" "$output_file" || echo 0)
    rm -f "$output_file"

    local end_time duration
    end_time=$(date +%s)
    duration=$((end_time - start_time))

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    if [[ $sync_result -eq 0 ]]; then
        echo -e "${gl_lv}✓ 本地反向同步完成!${gl_bai}"
        echo -e "${gl_bai}同步统计:${gl_bai}"
        echo -e "  - 任务名称: ${gl_hong}${name}${gl_bai}"
        echo -e "  - 同步方向: ${gl_lv}${target_path} ${gl_hong}-> ${gl_huang}${source_path}${gl_bai}"
        echo -e "  - 耗时: ${gl_zi}${duration}${gl_bai}"
        echo -e "  - 完成时间: ${gl_lv}$(date)${gl_bai}"
        echo -e "  - 同步结果: ${gl_lv}成功${gl_bai}"
    elif [[ $sync_result -eq 23 ]] && [[ $error_count -gt 0 ]]; then
        echo -e "${gl_huang}⚠ 反向同步部分完成,但有文件权限问题${gl_bai}"
        echo -e "${gl_bai}同步统计:${gl_bai}"
        echo -e "  - 任务名称: ${gl_hong}${name}${gl_bai}"
        echo -e "  - 同步方向: ${gl_lv}${target_path} ${gl_hong}-> ${gl_huang}${source_path}${gl_bai}"
        echo -e "  - 耗时: ${gl_zi}${duration}${gl_bai}"
        echo -e "  - 完成时间: ${gl_lv}$(date)${gl_bai}"
        echo -e "  - 同步结果: ${gl_huang}部分成功${gl_bai}"
        echo -e "  - 错误类型: 文件权限受限"
        echo -e "${gl_huang}建议解决方案:${gl_bai}"
        echo -e "  ${gl_bufan}1. ${gl_bai}重新编辑任务,选择'权限友好模式'"
        echo -e "  ${gl_bufan}2. ${gl_bai}在高级选项中选择'排除Windows系统目录'"
        echo -e "  ${gl_bufan}3. ${gl_bai}使用root权限执行"
    else
        echo -e "${gl_hong}✗ 反向同步失败! 错误代码: ${sync_result}${gl_bai}"
        echo -e "${gl_hong}可能的原因:${gl_bai}"
        echo -e "  ${gl_bufan}1. ${gl_bai}原源目录(现目标目录)权限不足 - 使用sudo或检查目录权限"
        echo -e "  ${gl_bufan}2. ${gl_bai}磁盘空间不足 - 检查目标磁盘空间"
        echo -e "  ${gl_bufan}3. ${gl_bai}文件被占用或权限问题 - 尝试重新编辑任务选择权限友好模式"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
    return $sync_result
}

local_forward_sync_menu() {
    clear
    echo ""
    echo -e "${gl_huang}>>> 执行正向同步 ${gl_bai}(${gl_huang}${gl_bai}-> ${gl_lv}目标${gl_bai})${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    local_list_tasks
    local task_num
    read -r -e -p "$(echo -e "${gl_bai}请输入要执行的任务编号(${gl_huang}0${gl_bai}返回): ")" task_num

    [ "$task_num" = "0" ] && { cancel_return "Rsync本地同步工具"; return 1; }
    [ -z "$task_num" ] && { cancel_empty "上一级选单"; return 1; }

    local_run_task "$task_num"
}

local_reverse_sync_menu() {
    clear
    echo ""
    echo -e "${gl_zi}>>> 执行反向同步 ${gl_bai}(${gl_huang}目标 ${gl_bai}-> ${gl_lv}${gl_bai})${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_huang}注意:反向同步会用目标目录文件覆盖源目录!${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    local_list_tasks
    local task_num

    read -r -e -p "$(echo -e "${gl_bai}请输入要执行反向同步的任务编号(${gl_huang}0${gl_bai}返回): ")" task_num

    [ "$task_num" = "0" ] && { cancel_return "Rsync本地同步工具"; return 1; }
    [ -z "$task_num" ] && { cancel_empty "上一级选单"; return 1; }

    local_run_task_reverse "$task_num"
}

local_fix_permission_menu() {
    clear
    echo ""
    echo -e "${gl_huang}>>> 修复权限问题${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}常见权限问题解决方案:${gl_bai}"
    echo -e "  ${gl_bufan}1. ${gl_bai}重新创建任务,选择'权限友好模式'"
    echo -e "  ${gl_bufan}2. ${gl_bai}在高级选项中选择'排除Windows系统目录'"
    echo -e "  ${gl_bufan}3. ${gl_bai}使用sudo权限执行同步"
    echo -e "  ${gl_bufan}4. ${gl_bai}修改源目录权限: chmod -R 755 /path/to/source"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

local_show_task_details() {
    local_init_globals || return 1
    echo ""
    echo -e "${gl_zi}>>> 查看本地同步任务详细信息${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    if [[ ! -f "$LOCAL_SYNC_CONFIG" ]]; then
        echo -e "${gl_huang}配置文件不存在,暂无同步任务${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        exit_animation
        return 0
    fi
    
    if [[ ! -s "$LOCAL_SYNC_CONFIG" ]]; then
        echo -e "${gl_huang}暂无同步任务${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        exit_animation
        return 0
    fi
    
    echo -e "${gl_bai}提示: 直接${gl_lv}回车${gl_bai}查看全部任务,输入${gl_huang}0${gl_bai}返回${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -r -e -p "$(echo -e "${gl_bai}请输入要查看的任务编号(${gl_huang}0${gl_bai}返回): ")" num
    [ "$num" = "0" ] && { cancel_return "Rsync本地同步工具"; return 1; }
    
    if [[ -z "$num" ]]; then
        echo ""
        echo -e "${gl_zi}>>> 所有本地同步任务详情${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        
        local line_num=1
        while IFS='|' read -r name source_path target_path options; do
            echo -e "${gl_bufan}任务 #${line_num}${gl_bai}"
            echo -e "  ${gl_bai}任务名称: ${gl_zi}$name${gl_bai}"
            echo -e "  ${gl_bai}源目录: ${gl_huang}$source_path${gl_bai}"
            echo -e "  ${gl_bai}目标目录: ${gl_lv}$target_path${gl_bai}"
            echo -e "  ${gl_bai}同步选项: ${gl_zi}$options${gl_bai}"
            
            if [[ -d "$source_path" ]]; then
                local source_size=$(du -sh "$source_path" 2>/dev/null | cut -f1)
                local source_count=$(find "$source_path" -type f 2>/dev/null | wc -l)
                echo -e "  ${gl_bai}源目录状态: ${gl_lv}存在${gl_bai}"
                echo -e "  ${gl_bai}源目录大小: ${gl_bai}${source_size:-未知}"
                echo -e "  ${gl_bai}源文件数量: ${gl_bai}${source_count}"
                
                if [[ ! -r "$source_path" ]]; then
                    echo -e "  ${gl_hong}警告: 源目录读取权限不足!${gl_bai}"
                fi
            else
                echo -e "  ${gl_hong}警告: 源目录不存在!${gl_bai}"
            fi
            
            if [[ -d "$target_path" ]]; then
                local target_size=$(du -sh "$target_path" 2>/dev/null | cut -f1)
                local target_count=$(find "$target_path" -type f 2>/dev/null | wc -l)
                echo -e "  ${gl_bai}目标目录状态: ${gl_lv}存在${gl_bai}"
                echo -e "  ${gl_bai}目标目录大小: ${gl_bai}${target_size:-未知}"
                echo -e "  ${gl_bai}目标文件数量: ${gl_bai}${target_count}"
                
                if [[ ! -w "$target_path" ]]; then
                    echo -e "  ${gl_hong}警告: 目标目录写入权限不足!${gl_bai}"
                fi
            else
                echo -e "  ${gl_huang}目标目录状态: ${gl_huang}不存在${gl_bai}"
            fi
            
            if [[ "$source_path" =~ ^// ]] || [[ "$source_path" =~ ^smb:// ]] || [[ "$target_path" =~ ^// ]] || [[ "$target_path" =~ ^smb:// ]]; then
                echo -e "  ${gl_bai}网络路径: ${gl_huang}${gl_bai}"
            fi
            
            echo -e "${gl_bai}磁盘空间信息:${gl_bai}"
            local source_disk=$(df -h "$source_path" 2>/dev/null | tail -1)
            local target_disk=$(df -h "$target_path" 2>/dev/null | tail -1)
            
            if [[ -n "$source_disk" ]]; then
                local source_fs=$(echo "$source_disk" | awk '{print $1}')
                local source_avail=$(echo "$source_disk" | awk '{print $4}')
                echo -e "  ${gl_bai}源磁盘可用空间: ${gl_bai}$source_avail (文件系统: $source_fs)"
            fi
            
            if [[ -n "$target_disk" ]]; then
                local target_fs=$(echo "$target_disk" | awk '{print $1}')
                local target_avail=$(echo "$target_disk" | awk '{print $4}')
                echo -e "  ${gl_bai}目标磁盘可用空间: ${gl_bai}$target_avail (文件系统: $target_fs)"
            fi
            
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            ((line_num++))
        done <"$LOCAL_SYNC_CONFIG"
        echo -e "${gl_lv}共找到 $((line_num-1)) 个同步任务${gl_bai}"
    else
        local task=$(sed -n "${num}p" "$LOCAL_SYNC_CONFIG" 2>/dev/null)
        if [[ -z "$task" ]]; then
            echo -e "${gl_hong}错误: 未找到任务 #$num${gl_bai}"
            exit_animation
            return
        fi
        
        IFS='|' read -r name source_path target_path options <<<"$task"
        
        echo ""
        echo -e "${gl_zi}>>> 本地同步任务 #$num 详情${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "  ${gl_bai}任务名称: ${gl_zi}$name${gl_bai}"
        echo -e "  ${gl_bai}源目录: ${gl_huang}$source_path${gl_bai}"
        echo -e "  ${gl_bai}目标目录: ${gl_lv}$target_path${gl_bai}"
        echo -e "  ${gl_bai}同步选项: ${gl_zi}$options${gl_bai}"
        
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "  ${gl_bai}同步选项解析:${gl_bai}"
        
        if [[ "$options" == *"-a"* ]]; then
            echo -e "  ${gl_bai}  - archive: 归档模式,保留所有文件属性${gl_bai}"
        fi
        if [[ "$options" == *"-v"* ]]; then
            echo -e "  ${gl_bai}  - verbose: 详细输出模式${gl_bai}"
        fi
        if [[ "$options" == *"-h"* ]]; then
            echo -e "  ${gl_bai}  - human-readable: 人类可读的文件大小${gl_bai}"
        fi
        if [[ "$options" == *"-z"* ]]; then
            echo -e "  ${gl_bai}  - compress: 传输时压缩数据${gl_bai}"
        fi
        if [[ "$options" == *"--progress"* ]]; then
            echo -e "  ${gl_bai}  - progress: 显示传输进度${gl_bai}"
        fi
        if [[ "$options" == *"--delete"* ]]; then
            echo -e "  ${gl_bai}  - delete: 删除目标目录中多余的文件${gl_bai}"
        fi
        if [[ "$options" == *"--delete-delay"* ]]; then
            echo -e "  ${gl_bai}  - delete-delay: 延迟删除文件,传输完成后删除${gl_bai}"
        fi
        if [[ "$options" == *"--checksum"* ]]; then
            echo -e "  ${gl_bai}  - checksum: 基于校验和而非大小和时间决定是否跳过${gl_bai}"
        fi
        if [[ "$options" == *"--no-perms"* ]]; then
            echo -e "  ${gl_bai}  - no-perms: 不保留权限${gl_bai}"
        fi
        if [[ "$options" == *"--no-owner"* ]]; then
            echo -e "  ${gl_bai}  - no-owner: 不保留所有者${gl_bai}"
        fi
        if [[ "$options" == *"--no-group"* ]]; then
            echo -e "  ${gl_bai}  - no-group: 不保留组${gl_bai}"
        fi
        if [[ "$options" == *"--bwlimit"* ]]; then
            local bwlimit=$(echo "$options" | grep -o -- "--bwlimit=[0-9]*" | cut -d= -f2)
            echo -e "  ${gl_bai}  - bwlimit: 限速 ${bwlimit}KB/s${gl_bai}"
        fi
        if [[ "$options" == *"--exclude"* ]]; then
            local excludes=$(echo "$options" | grep -o -- "--exclude='[^']*'" || echo "$options" | grep -o -- '--exclude=[^[:space:]]*')
            echo -e "  ${gl_bai}  - exclude: 排除以下文件:${gl_bai}"
            for exclude in $excludes; do
                local pattern=$(echo "$exclude" | sed "s/--exclude='//" | sed "s/'$//" | sed "s/--exclude=//")
                echo -e "    ${gl_bai}    * $pattern${gl_bai}"
            done
        fi
        
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "  ${gl_bai}源目录状态检查:${gl_bai}"
        
        if [[ -d "$source_path" ]]; then
            local source_size=$(du -sh "$source_path" 2>/dev/null | cut -f1)
            local source_file_count=$(find "$source_path" -type f 2>/dev/null | wc -l)
            local source_dir_count=$(find "$source_path" -type d 2>/dev/null | wc -l)
            
            echo -e "  ${gl_bai}  - 存在: ${gl_lv}${gl_bai}"
            echo -e "  ${gl_bai}  - 总大小: ${gl_bai}$source_size"
            echo -e "  ${gl_bai}  - 文件数量: ${gl_bai}$source_file_count"
            echo -e "  ${gl_bai}  - 目录数量: ${gl_bai}$source_dir_count"
            
            if [[ -r "$source_path" ]]; then
                echo -e "  ${gl_bai}  - 读取权限: ${gl_lv}正常${gl_bai}"
            else
                echo -e "  ${gl_bai}  - 读取权限: ${gl_hong}不足${gl_bai}"
            fi
            
            local mod_time=$(stat -c "%y" "$source_path" 2>/dev/null | cut -d'.' -f1)
            echo -e "  ${gl_bai}  - 最后修改: ${gl_bai}${mod_time:-未知}"
            
        else
            echo -e "  ${gl_bai}  - 存在: ${gl_hong}${gl_bai}"
            echo -e "  ${gl_bai}  - 状态: ${gl_hong}目录不存在!${gl_bai}"
        fi
        
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "  ${gl_bai}目标目录状态检查:${gl_bai}"
        
        if [[ -d "$target_path" ]]; then
            local target_size=$(du -sh "$target_path" 2>/dev/null | cut -f1)
            local target_file_count=$(find "$target_path" -type f 2>/dev/null | wc -l)
            local target_dir_count=$(find "$target_path" -type d 2>/dev/null | wc -l)
            
            echo -e "  ${gl_bai}  - 存在: ${gl_lv}${gl_bai}"
            echo -e "  ${gl_bai}  - 总大小: ${gl_bai}$target_size"
            echo -e "  ${gl_bai}  - 文件数量: ${gl_bai}$target_file_count"
            echo -e "  ${gl_bai}  - 目录数量: ${gl_bai}$target_dir_count"
            
            if [[ -w "$target_path" ]]; then
                echo -e "  ${gl_bai}  - 写入权限: ${gl_lv}正常${gl_bai}"
            else
                echo -e "  ${gl_bai}  - 写入权限: ${gl_hong}不足${gl_bai}"
            fi
            
            local disk_info=$(df -h "$target_path" 2>/dev/null | tail -1)
            if [[ -n "$disk_info" ]]; then
                local fs_type=$(echo "$disk_info" | awk '{print $1}')
                local total_space=$(echo "$disk_info" | awk '{print $2}')
                local used_space=$(echo "$disk_info" | awk '{print $3}')
                local avail_space=$(echo "$disk_info" | awk '{print $4}')
                local use_percent=$(echo "$disk_info" | awk '{print $5}')
                
                echo -e "  ${gl_bai}  - 文件系统: ${gl_bai}$fs_type"
                echo -e "  ${gl_bai}  - 总空间: ${gl_bai}$total_space"
                echo -e "  ${gl_bai}  - 已用空间: ${gl_bai}$used_space ($use_percent)"
                echo -e "  ${gl_bai}  - 可用空间: ${gl_bai}$avail_space"
                
                if [[ -n "$source_size" ]] && [[ "$source_size" =~ ^[0-9.]+[KMGTPE]?$ ]]; then
                    local source_bytes=$(echo "$source_size" | numfmt --from=iec 2>/dev/null)
                    local avail_bytes=$(echo "$avail_space" | numfmt --from=iec 2>/dev/null)
                    
                    if [[ -n "$source_bytes" ]] && [[ -n "$avail_bytes" ]] && [[ "$source_bytes" -gt "$avail_bytes" ]]; then
                        echo -e "  ${gl_hong}警告: 目标磁盘空间不足!${gl_bai}"
                        echo -e "  ${gl_hong}源目录大小 ($source_size) 大于可用空间 ($avail_space)${gl_bai}"
                    fi
                fi
            fi
            
        else
            echo -e "  ${gl_bai}  - 存在: ${gl_huang}${gl_bai}"
            echo -e "  ${gl_bai}  - 状态: 目录不存在,执行同步时会自动创建${gl_bai}"
        fi
        
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "  ${gl_bai}路径类型检测:${gl_bai}"
        
        if [[ "$source_path" =~ ^// ]] || [[ "$source_path" =~ ^smb:// ]] || mount | grep -q " on $source_path "; then
            echo -e "  ${gl_bai}  - 源路径类型: ${gl_huang}网络共享/挂载点${gl_bai}"
        elif [[ "$source_path" =~ ^/mnt/ ]] || [[ "$source_path" =~ ^/media/ ]]; then
            echo -e "  ${gl_bai}  - 源路径类型: ${gl_huang}挂载点${gl_bai}"
        else
            echo -e "  ${gl_bai}  - 源路径类型: ${gl_lv}本地目录${gl_bai}"
        fi
        
        if [[ "$target_path" =~ ^// ]] || [[ "$target_path" =~ ^smb:// ]] || mount | grep -q " on $target_path "; then
            echo -e "  ${gl_bai}  - 目标路径类型: ${gl_huang}网络共享/挂载点${gl_bai}"
        elif [[ "$target_path" =~ ^/mnt/ ]] || [[ "$target_path" =~ ^/media/ ]]; then
            echo -e "  ${gl_bai}  - 目标路径类型: ${gl_huang}挂载点${gl_bai}"
        else
            echo -e "  ${gl_bai}  - 目标路径类型: ${gl_lv}本地目录${gl_bai}"
        fi
        
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "  ${gl_bai}执行命令预览:${gl_bai}"
        echo -e "  ${gl_bai}  - 正向同步: ${gl_zi}rsync $options \"$source_path\" \"$target_path\"${gl_bai}"
        echo -e "  ${gl_bai}  - 反向同步: ${gl_zi}rsync $options \"$target_path\" \"$source_path\"${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "  ${gl_bai}定时任务检查:${gl_bai}"
        
        local cron_count=$(crontab -l 2>/dev/null | grep -c "local_rsync_run $num")
        if [[ $cron_count -gt 0 ]]; then
            local cron_jobs=$(crontab -l 2>/dev/null | grep "local_rsync_run $num")
            echo -e "  ${gl_bai}  - 定时任务: ${gl_lv}已设置 ($cron_count 个)${gl_bai}"
            while IFS= read -r cron_line; do
                echo -e "  ${gl_bai}    * $cron_line${gl_bai}"
            done <<< "$cron_jobs"
        else
            echo -e "  ${gl_bai}  - 定时任务: ${gl_huang}未设置${gl_bai}"
        fi
        
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "  ${gl_bai}同步建议:${gl_bai}"
        
        if [[ "$options" == *"--delete"* ]]; then
            echo -e "  ${gl_bai}  - ${gl_huang}⚠ 警告: 此任务会删除目标目录中多余的文件${gl_bai}"
        fi
        
        if [[ ! -d "$source_path" ]]; then
            echo -e "  ${gl_bai}  - ${gl_hong}✗ 错误: 源目录不存在,同步将失败${gl_bai}"
        fi
        
        if [[ ! -d "$target_path" ]] && [[ ! -w "$(dirname "$target_path")" ]]; then
            echo -e "  ${gl_bai}  - ${gl_huang}⚠ 注意: 目标目录不存在且父目录不可写,同步将失败${gl_bai}"
        fi
        
        if [[ "$options" != *"--no-perms"* ]] && [[ "$options" != *"--no-owner"* ]] && [[ "$options" != *"--no-group"* ]]; then
            if [[ "$source_path" =~ ^// ]] || [[ "$target_path" =~ ^// ]]; then
                echo -e "  ${gl_bai}  - ${gl_huang}💡 建议: 网络共享建议使用权限友好模式${gl_bai}"
            fi
        fi
    fi
    
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

local_rsync_manager() {
    local menu_name="${1:-上一级选单}"
    local_init_globals || return 1

    while true; do
        install sshpass rsync
        clear
        local_list_tasks
        echo ""
        local_view_schedules
        echo ""
        echo -e "${gl_zi}>>> Rsync本地同步工具${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo "本地目录之间同步,支持增量同步,高效稳定。"
        df -hT | grep -E "(cifs|smb)" 2>/dev/null || echo -e "${gl_huang}无Samba/CIFS挂载${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_bufan}1.  ${gl_bai}创建新任务           ${gl_bufan}2.  ${gl_bai}查看任务详情"
        echo -e "${gl_bufan}3.  ${gl_bai}执行正向同步         ${gl_bufan}4.  ${gl_bai}执行反向同步"
        echo -e "${gl_bufan}5.  ${gl_bai}批量执行所有任务     ${gl_bufan}6.  ${gl_bai}删除同步任务"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_bufan}7.  ${gl_bai}创建定时任务         ${gl_bufan}8.  ${gl_bai}删除定时任务"
        echo -e "${gl_bufan}9.  ${gl_bai}编辑cron文件         ${gl_bufan}10. ${gl_bai}查看cron文件"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_hong}0.  ${gl_bai}退出脚本"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

        read -r -e -p "请输入你的选择: " choice
        case $choice in
        1)  local_add_task ;;
        2)  local_show_task_details ;;
        3)  local_forward_sync_menu ;;
        4)  local_reverse_sync_menu ;;
        5)  local_run_all_tasks ;;
        6)  local_delete_task ;;
        7)  local_schedule_task ;;
        8)  local_delete_schedule ;;
        9)  edit_crontab; continue ;;
        10) list_beautify_all ;;
        0) exit_script ;;
        *) handle_invalid_input ;;
        esac
    done
}

local_rsync_manager

创建本地脚本

new_script="new_test.sh"

cat > "$new_script" << 'EOF'
#!/bin/bash

# 粘贴脚本源码

EOF

# 保留本地脚本,去掉 rm -f "$new_script"
chmod +x "$new_script" && ./"$new_script" && rm -f "$new_script"