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

pve_file_menu

脚本

PVE 系统下的交互式文件管理器,提供镜像文件管理、备份文件管理。

pve_file_menu

PVE 系统下的交互式文件管理器,提供镜像文件管理、备份文件管理。

一键脚本

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

效果预览

执行脚本效果预览

脚本源码

#!/bin/bash

SCRIPT_WORKDIR=""

parse_arguments() {
    while [[ $# -gt 0 ]]; do
        case "$1" in
            -w|--workdir)
                if [[ -n "${2:-}" ]]; then
                    SCRIPT_WORKDIR="$2"
                    shift 2
                else
                    echo "错误: -w/--workdir 需要参数值" >&2
                    exit 1
                fi
                ;;
            -h|--help)
                cat << 'HELPEOF'
用法: linux_file_menu.sh [选项] [工作路径]

描述: Linux 文件管理器 - 完整功能版,支持39项操作

选项:
  -w, --workdir <路径>    指定工作路径
  -h, --help              显示此帮助信息

示例:
  ./linux_file_menu.sh /home/user/documents
  ./linux_file_menu.sh --workdir /tmp
  ./linux_file_menu.sh
HELPEOF
                exit 0
                ;;
            -*)
                echo "未知选项: $1" >&2
                exit 1
                ;;
            *)
                if [[ -z "$SCRIPT_WORKDIR" && -d "$1" ]]; then
                    SCRIPT_WORKDIR="$1"
                fi
                shift
                ;;
        esac
    done

    if [[ -z "$SCRIPT_WORKDIR" ]]; then
        SCRIPT_WORKDIR="$(pwd)"
    fi

    if [[ ! -d "$SCRIPT_WORKDIR" ]]; then
        echo "错误: 工作路径不存在: $SCRIPT_WORKDIR" >&2
        exit 1
    fi
}

parse_arguments "$@"

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

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; }

handle_invalid_input() {
    echo -ne "\r${gl_huang}无效的输入,请重新输入! ${gl_zi} 1 ${gl_huang} 秒后返回"
    sleep 1
    echo -e "\r${gl_lv}无效的输入,请重新输入! ${gl_zi}0${gl_lv} 秒后返回"
    sleep 0.5
    return 2
}

handle_y_n() {
    echo -e "${gl_hong}无效的选择,请输入 ${gl_bai}(${gl_lv}y${gl_bai}${gl_hong}N${gl_bai})${gl_hong}${gl_bai}"
    sleep 1
    echo -e "${gl_huang}无效的选择,请输入 ${gl_bai}(${gl_lv}y${gl_bai}${gl_hong}N${gl_bai})${gl_huang}${gl_bai}"
    sleep 1
    echo -e "${gl_lv}无效的选择,请输入 ${gl_bai}(${gl_lv}y${gl_bai}${gl_hong}N${gl_bai})${gl_lv}${gl_bai}"
    sleep 0.5
    return 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 -r -p ""
    echo ""
    clear
}

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
    elif 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 -e "${gl_lv}即将返回到 ${gl_huang}${menu_name}${gl_lv}${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
    sleep 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
}

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
}

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

    local pkg mgr install_success=false
    for pkg in "$@"; do
        if command -v "$pkg" &>/dev/null; then
            continue
        fi
        echo -e "${gl_huang}开始安装:${gl_bai}${pkg}"
        for mgr in apt dnf yum apk pacman; do
            if ! command -v "$mgr" &>/dev/null; then
                continue
            fi
            case $mgr in
                apt)
                    apt update -y && apt install -y "$pkg" && install_success=true
                    ;;
                dnf)
                    dnf install -y "$pkg" && install_success=true
                    ;;
                yum)
                    yum install -y "$pkg" && install_success=true
                    ;;
                apk)
                    apk add "$pkg" && install_success=true
                    ;;
                pacman)
                    pacman -S --noconfirm "$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
    done
}

check_directory_empty() {
    local dir="${1:-.}"
    local title="${2:-检查目录}"
    local exit_on_empty="${3:-true}"

    if [ ! -d "$dir" ]; then
        echo ""
        echo -e "${gl_zi}>>> ${title}${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_hong}错误:目录不存在 ${gl_huang}${dir}${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_lv}即将退出${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
        sleep_fractional 1
        return 2
    fi

    if [ -z "$(ls -A "$dir" 2>/dev/null)" ]; then
        if [ "$exit_on_empty" != "true" ] && [ "$exit_on_empty" != "1" ]; then
            echo -e "${gl_huang}当前目录为空:${gl_bai}(${gl_lv}$(pwd)${gl_bai})"
            return 0
        fi
        echo ""
        echo -e "${gl_zi}>>> ${title}${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_huang}当前目录为空:${gl_bai}(${gl_lv}$(pwd)${gl_bai})"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_lv}即将退出${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
        sleep_fractional 1
        return 1
    fi
    return 0
}
show_directory_list() {
    local base_path="${1:-.}"
    local items_per_line="${2:-4}"
    local show_hidden="${3:-false}"
    local exit_on_empty="${4:-true}"
    local return_array_var="${5:-}"

    local dir_array=()
    for dir in "$base_path"/*/; do
        [[ -d "$dir" ]] || continue
        local dir_name
        dir_name=$(basename "$dir")

        if [[ "$show_hidden" == "true" || "$show_hidden" == "1" ]]; then
            dir_array+=("$dir_name")
        elif [[ ! "$dir_name" =~ ^\. ]]; then
            dir_array+=("$dir_name")
        fi
    done

    if [[ ${#dir_array[@]} -eq 0 ]]; then
        echo -e "${gl_huang}当前目录为空${gl_bai}"
        if [[ "$exit_on_empty" == "true" || "$exit_on_empty" == "1" ]]; then
            if [[ -n "${return_array_var:-}" ]]; then
                eval "${return_array_var}=()"
            fi
            return 0
        fi
    fi

    mapfile -t dir_array < <(printf '%s\n' "${dir_array[@]}" | sort)

    if [[ -n "${return_array_var:-}" ]]; then
        eval "${return_array_var}=($(printf '%q ' "${dir_array[@]}"))"
    fi

    _sdl_get_width() {
        local s="${1:-}"
        local w=0 len=${#s} i code
        for ((i = 0; i < len; i++)); do
            code=$(printf '%d' "'${s:i:1}")
            if [[ $code -lt 128 ]]; then
                ((w++))
            elif [[ $code -ge 0x4E00 && $code -le 0x9FFF ]] ||
                [[ $code -ge 0x3400 && $code -le 0x4DBF ]] ||
                [[ $code -ge 0xF900 && $code -le 0xFAFF ]] ||
                [[ $code -ge 0x3000 && $code -le 0x303F ]] ||
                [[ $code -ge 0xFF00 && $code -le 0xFFEF ]]; then
                ((w += 2))
            else
                ((w += 2))
            fi
        done
        echo $w
    }

    local max_display_width=0 d width
    for d in "${dir_array[@]}"; do
        width=$(_sdl_get_width "$d")
        (($width > max_display_width)) && max_display_width=$width
    done

    local column_width=$((max_display_width + 4))
    local count=0 i index_str current_width padding
    for i in "${!dir_array[@]}"; do
        count=$((i + 1))
        printf -v index_str "%2d." "$count"
        current_width=$(_sdl_get_width "${dir_array[i]}")
        padding=$((column_width - current_width))
        printf "${gl_bufan}%s${gl_bai} %s" "$index_str" "${dir_array[i]}"
        for ((s = 0; s < padding; s++)); do
            printf " "
        done
        if (((i + 1) % items_per_line == 0)); then
            echo
        fi
    done
    if ((count % items_per_line != 0)); then
        echo
    fi
    return 0
}

declare -a LIST_FILES_ARRAY=()
LIST_FILES_COUNT=0

list_files() {
    local target_dir="${1:-.}"
    local show_hidden="${2:-0}"
    local custom_cols="${3:-2}"
    local dir="${CURRENT_DIR:-.}"        # 使用环境变量
    
    LIST_FILES_ARRAY=()
    LIST_FILES_COUNT=0
    
    if [[ ! -d "$target_dir" ]]; then
        log_error "目录不存在: $target_dir"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    local original_dir="$(pwd)"
    
    if ! cd "$target_dir" 2>/dev/null; then
        log_error "无法进入目录: $target_dir"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    local file_items=()
    local dir_items=()
    
    if [[ "$show_hidden" == "0" ]]; then
        for item in *; do
            [[ "$item" == "*" ]] && continue
            
            if [[ -f "$item" ]]; then
                file_items+=("$item")
            elif [[ -d "$item" ]]; then
                dir_items+=("$item")
            fi
        done
    else
        for item in *; do
            [[ "$item" == "*" ]] && continue
            
            if [[ -f "$item" ]]; then
                file_items+=("$item")
            elif [[ -d "$item" ]]; then
                dir_items+=("$item")
            fi
        done
        
        for item in .*; do
            [[ "$item" == "." ]] && continue
            [[ "$item" == ".." ]] && continue
            [[ "$item" == ".*" ]] && continue
            
            if [[ -f "$item" ]]; then
                file_items+=("$item")
            elif [[ -d "$item" ]]; then
                dir_items+=("$item")
            fi
        done
    fi
    
    cd "$original_dir" || return 1
    
    LIST_FILES_ARRAY=("${dir_items[@]}" "${file_items[@]}")
    LIST_FILES_COUNT=${#LIST_FILES_ARRAY[@]}
    
    calculate_display_width() {
        local str="$1"
        local width=0
        local i
        local char
        local utf8_char
        
        for ((i=0; i<${#str}; i++)); do
            char="${str:$i:1}"
            utf8_char=$(printf "%s" "$char" | od -An -tx1 | tr -d ' ')
            
            if [[ ${#utf8_char} -eq 2 && "0x$utf8_char" -le "0x7F" ]]; then
                ((width++))
            else
                ((width += 2))
            fi
        done
        echo "$width"
    }
    
    format_fixed_width() {
        local str="$1"
        local fixed_width="${2:-18}"
        
        local result=""
        local char_width=0
        local total_width=0
        
        total_width=$(calculate_display_width "$str")
        
        if [[ $total_width -le $fixed_width ]]; then
            result="$str"
            char_width=$total_width
        else
            local ext=""
            local name_part="$str"
            local has_extension=false
            
            for ((i=${#str}-1; i>=0; i--)); do
                if [[ "${str:$i:1}" == "." && $i -gt 0 && $i -lt $((${#str}-1)) ]]; then
                    ext="${str:$i}"
                    name_part="${str:0:$i}"
                    has_extension=true
                    break
                fi
            done
            
            local ext_width=0
            if $has_extension; then
                ext_width=$(calculate_display_width "$ext")
            fi
            
            local reserved_for_ellipsis=2
            local name_available_width=$((fixed_width - ext_width - reserved_for_ellipsis))
            if [[ $name_available_width -lt 1 ]]; then
                name_available_width=1
            fi
            
            local truncated_name=""
            local current_width=0
            local i=0
            
            while [[ $i -lt ${#name_part} && $current_width -lt $name_available_width ]]; do
                local char="${name_part:$i:1}"
                local char_w=1
                
                local utf8_char=$(printf "%s" "$char" | od -An -tx1 | tr -d ' ')
                if [[ ${#utf8_char} -gt 2 || ("0x$utf8_char" -gt "0x7F" && ${#utf8_char} -eq 2) ]]; then
                    char_w=2
                fi
                
                if [[ $((current_width + char_w)) -le $name_available_width ]]; then
                    truncated_name="${truncated_name}${char}"
                    current_width=$((current_width + char_w))
                    ((i++))
                else
                    break
                fi
            done
            
            truncated_name="${truncated_name}.."
            current_width=$((current_width + reserved_for_ellipsis))
            
            if $has_extension; then
                result="${truncated_name}${ext}"
                char_width=$((current_width + ext_width))
            else
                result="$truncated_name"
                char_width=$current_width
            fi
        fi
        
        while [[ $char_width -lt $fixed_width ]]; do
            result="${result} "
            ((char_width++))
        done
        
        echo "$result"
    }
    
    local items_per_line="$custom_cols"
    ((items_per_line < 1)) && items_per_line=2
    ((items_per_line > 4)) && items_per_line=4
    
    local name_width
    local total_available_width=80
    local column_padding=3  # 列间距
    
    case $items_per_line in
        1) 
            name_width=70 
            ;;
        2) 
            name_width=$(( (total_available_width - column_padding) / 2 ))
            ;;
        3) 
            name_width=$(( (total_available_width - 2 * column_padding) / 3 ))
            ;;
        4) 
            name_width=$(( (total_available_width - 3 * column_padding) / 4 ))
            ;;
        *) 
            name_width=30 
            ;;
    esac
    
    ((name_width < 8)) && name_width=8
    ((name_width > 70)) && name_width=70
    
    echo ""
    echo -e "${gl_huang}>>> 当前目录文件列表:${gl_bai}(${gl_lv}$(pwd)${gl_bai})"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    if [ -z "$(ls -A)" ]; then
        echo -e "${gl_huang}当前目录为空${gl_bai}"
    fi

    local count=0
    for ((i=0; i<LIST_FILES_COUNT; i++)); do
        ((count++))
        local item="${LIST_FILES_ARRAY[$i]}"
        local item_path="$target_dir/$item"
        
        local color="${gl_lv}"  # 默认文件绿色
        if [[ -d "$item_path" ]]; then
            color="${gl_zi}"    # 目录紫色
        elif [[ -x "$item_path" ]]; then
            color="${gl_huang}"  # 可执行文件黄色
        elif [[ "$item" == .* ]]; then
            color="${gl_hui}"    # 隐藏文件灰色
        elif [[ "$item" =~ \.(zip|tar|gz|bz2|7z|rar)$ ]]; then
            color="${gl_hong}"  # 压缩文件红色
        elif [[ "$item" =~ \.(sh|bash|zsh)$ ]]; then
            color="${gl_lan}"   # 脚本文件蓝色
        elif [[ "$item" =~ \.(txt|md|conf|ini|cfg)$ ]]; then
            color="${gl_qing}"  # 配置文件青色
        fi
        
        local display_name=$(format_fixed_width "$item" $name_width)
        
        printf "${gl_bufan}%3d.${gl_bai} ${color}%s" "$count" "$display_name"
        
        if ((count % items_per_line != 0 && count < LIST_FILES_COUNT)); then
            case $items_per_line in
                2) printf "   " ;;
                3) printf "  " ;;
                4) printf " " ;;
                *) printf "  " ;;
            esac
        fi
        
        if ((count % items_per_line == 0 || count == LIST_FILES_COUNT)); then
            echo ""
        fi
    done
    
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}目录:${gl_zi}${gl_bai} 文件:${gl_lv}${gl_bai} 隐藏:${gl_hui}${gl_bai} 压缩:${gl_hong}${gl_bai} ${gl_bai}脚本:${gl_lan}${gl_bai} 配置:${gl_qing}${gl_bai} 执行:${gl_huang}${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    return 0
}

display_storage_info() {
    local target_path="${1:-.}"
    local show_all="${2:-false}"

    echo -e ""
    echo -e "${gl_zi}>>> 存储信息汇总${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local disk_info
    disk_info=$(df -h "$target_path" 2>/dev/null | tail -1)
    local total=$(echo "$disk_info" | awk '{print $2}')
    local used=$(echo "$disk_info" | awk '{print $3}')
    local avail=$(echo "$disk_info" | awk '{print $4}')
    local use_pct=$(echo "$disk_info" | awk '{print $5}')
    local mount_point=$(echo "$disk_info" | awk '{print $6}')
    local fs_type=$(df -T "$target_path" 2>/dev/null | tail -1 | awk '{print $2}')

    echo -e "${gl_bai}磁盘信息 (${mount_point}):"
    echo -e "  ${gl_bai}文件系统: ${gl_huang}${fs_type:-未知}${gl_bai}"
    echo -e "  ${gl_bai}总容量:   ${gl_lv}${total}${gl_bai}"
    echo -e "  ${gl_bai}已使用:   ${gl_huang}${used}${gl_bai} (${use_pct})"
    echo -e "  ${gl_bai}可用空间: ${gl_lv}${avail}${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local dir_info
    dir_info=$(du -sh "$target_path" 2>/dev/null)
    local dir_size=$(echo "$dir_info" | awk '{print $1}')
    local dir_path=$(echo "$dir_info" | awk '{print $2}')

    echo -e "${gl_bai}当前目录: ${gl_huang}${dir_path}${gl_bai}"
    echo -e "  ${gl_bai}目录总大小: ${gl_lv}${dir_size}${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    if [[ "$show_all" == "true" ]]; then
        echo -e "${gl_bai}子目录大小:"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        du -h --max-depth=1 "$target_path" 2>/dev/null | sort -hr | head -10 | while read -r size path; do
            echo -e "  ${gl_huang}$(printf '%-10s' "$size")${gl_bai}$(basename "$path")"
        done
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    fi

    echo -e "${gl_bai}文件类型统计:"
    local ext_count
    ext_count=$(find "$target_path" -maxdepth 1 -type f 2>/dev/null | sed 's/.*\.//' | sort | uniq -c | sort -rn | head -5)
    if [[ -n "$ext_count" ]]; then
        echo "$ext_count" | while read -r count ext; do
            echo -e "  ${gl_lv}$(printf '%4s' "$count")${gl_bai} 个 .${ext} 文件"
        done
    else
        echo -e "  ${gl_hui}无文件${gl_bai}"
    fi
}

root_use() {
    if [[ $EUID -ne 0 ]]; then
        if command -v sudo >/dev/null 2>&1; then
            echo -e "${gl_huang}提示: 某些操作需要 root 权限${gl_bai}"
            echo -e "${gl_huang}如需权限,请使用 sudo 运行此脚本${gl_bai}"
        elif command -v doas >/dev/null 2>&1; then
            echo -e "${gl_huang}提示: 某些操作需要 root 权限${gl_bai}"
        fi
    fi
}

enter_directory() {
    local current_path="$(pwd)"
    local return_target="${1:-文件管理器}"  # 接收参数,默认值为"文件管理器"
    clear
    local dirs=()
    echo -e "${gl_huang}>>> 当前目录子目录列表:${gl_bai}(${gl_lv}$current_path${gl_bai})"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    show_directory_list "." 2 false true "dirs"

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e ""
    echo -e "${gl_zi}>>> 进入指定目录${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -r -e -p "$(echo -e "${gl_bai}请输入 ${gl_huang}序号${gl_bai} ${gl_lv}目录名${gl_bai} ${gl_lan}路径${gl_bai} (${gl_hui}..上级${gl_bai} ${gl_zi}~家${gl_bai} ${gl_hong}/根${gl_bai}) 或 ${gl_huang}0${gl_bai}返回: ")" input

    if [[ -z "$input" ]]; then
        cancel_empty
        return 1
    fi
    
    if [[ "$input" == "0" ]]; then
        cancel_return "$return_target"
        return 1
    fi

    if [[ "$input" =~ ^[0-9]+$ ]]; then
        if [[ ${#dirs[@]} -eq 0 ]]; then
            echo -e "${gl_hong}当前目录没有可用的子目录列表,无法通过序号选择${gl_bai}"
            exit_animation    # 即将退出动画
            return 1
        fi

        if [[ "$input" -ge 1 ]] && [[ "$input" -le ${#dirs[@]} ]]; then
            local selected_dir="${dirs[$((input - 1))]}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_bai}已选择: ${gl_lv}$selected_dir${gl_bai}"

            if cd "$selected_dir" 2>/dev/null; then
                echo -e "${gl_bai}成功进入目录: ${gl_lv}$(pwd)${gl_bai}"
            else
                echo -e "${gl_hong}无法进入目录: $selected_dir${gl_bai}"
                echo -e "${gl_hong}可能的原因:${gl_bai}"
                echo -e "${gl_huang}1. 目录不存在${gl_bai}"
                echo -e "${gl_huang}2. 没有访问权限${gl_bai}"
                echo -e "${gl_huang}3. 输入路径有误${gl_bai}"
            fi
        else
            echo -e "${gl_hong}序号 $input 超出范围 (1-${#dirs[@]})${gl_bai}"
        fi
    else
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_lv}尝试进入: $input${gl_bai}"

        local target_path="$input"
        if [[ "$input" == ".." ]]; then
            target_path=".."
        elif [[ "$input" == "~" ]]; then
            target_path=~
        elif [[ "$input" == "/" ]]; then
            target_path="/"
        fi

        if cd "$target_path" 2>/dev/null; then
            local new_path="$(pwd)"
            echo -e "${gl_lv}成功进入目录: $new_path${gl_bai}"

            if [[ ! -d "$new_path" ]]; then
                echo -e "${gl_hong}警告:目标不是一个有效的目录${gl_bai}"
                cd "$current_path" 2>/dev/null
            fi
        else
            echo -e "${gl_hong}无法进入目录: $input${gl_bai}"
            echo -e "${gl_hong}可能的原因:${gl_bai}"
            echo -e "${gl_huang}1. 路径不存在${gl_bai}"
            echo -e "${gl_huang}2. 没有访问权限${gl_bai}"
            echo -e "${gl_huang}3. 不是有效的目录${gl_bai}"
            echo -e "${gl_huang}4. 路径格式错误${gl_bai}"

            if [[ -e "$input" ]] && [[ ! -d "$input" ]]; then
                echo -e "${gl_huang}注意:'$input' 是一个文件,不是目录${gl_bai}"
            fi
        fi
    fi

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_huang}即将进入 ${gl_lv}$(basename "$(pwd)")${gl_huang} 目录${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
    sleep_fractional 1.6
    return 0
}

create_directory() {
    local return_target="${1:-文件管理器}"  # 接收参数,默认值为"文件管理器"
    read -r -e -p "$(echo -e "${gl_bai}请输入要创建的目录名(${gl_huang}0${gl_bai}返回): ")" dirname
    [ -z "$dirname" ] && { cancel_empty "上一级选单"; return 1; }                        # break 或 continue 或 return ,视上下文而定
    [ "$dirname" == "0" ] && { cancel_return "$return_target"; return 1; }  # break 或 continue 或 return ,视上下文而定
    mkdir -p "$dirname" && sleep_fractional 0.6 && echo -e "${gl_lv}目录已创建${gl_bai}" || echo "${gl_hong}创建失败${gl_bai}"
    return 0
}

modify_directory_permissions() {
    echo -e ""
    echo -e "${gl_zi}>>> 修改目录权限${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    local dir_list=()

    if show_directory_list "." 4 false true "dir_list"; then
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        read -r -e -p "$(echo -e "${gl_bai}请输入目录序号或路径(${gl_huang}0${gl_bai}返回): ")" input

        [ -z "$input" ] && { cancel_empty "上一级选单"; return 1; }                      # break 或 continue 或 return ,视上下文而定
        [ "$input" == "0" ] && { cancel_return "文件管理器"; return 1; }     # break 或 continue 或 return ,视上下文而定
        local target_dir=""
        
        if [[ "$input" =~ ^[0-9]+$ ]] && [[ "$input" -ge 1 ]] && [[ "$input" -le ${#dir_list[@]} ]]; then
            target_dir="${dir_list[$((input-1))]}"
        else
            target_dir="$input"
        fi
        
        local old_perm old_owner
        old_perm=$(stat -c '%a' "$target_dir" 2>/dev/null || stat -f '%Lp' "$target_dir" 2>/dev/null)
        old_owner=$(stat -c '%U:%G' "$target_dir" 2>/dev/null || stat -f '%Su:%Sg' "$target_dir" 2>/dev/null)
        
        echo -e ""
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_bai}[${gl_huang}修改前${gl_bai}]"
        echo -e "  ${gl_bai}目录: ${gl_bufan}$target_dir${gl_bai}"
        echo -e "  ${gl_bai}权限: ${gl_huang}$old_perm ($(stat -c '%A' "$target_dir" 2>/dev/null || stat -f '%Sp' "$target_dir" 2>/dev/null))"
        echo -e "  ${gl_bai}所有者: ${gl_lv}$old_owner${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        
        read -e -p "$(echo -e "${gl_bai}请输入新权限 (如 ${gl_huang}755${gl_bai}) (${gl_huang}0${gl_bai}返回)): ")" perm

        [ -z "$perm" ] && { cancel_empty "上一级选单"; return 1; }                       # break 或 continue 或 return ,视上下文而定
        [ "$perm" == "0" ] && { cancel_return "文件管理器"; return 1; }  # break 或 continue 或 return ,视上下文而定
        
        if [[ ! "$perm" =~ ^[0-7]{3,4}$ ]]; then
            echo -e "${gl_hong}错误:权限格式不正确,请输入3-4位数字 (755, 644)${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            exit_animation    # 即将退出动画
            return 1
        fi
        
        if chmod "$perm" "$target_dir"; then
            echo -e ""
            echo -e "${gl_lv}✓ 权限修改成功${gl_bai}"
            
            local new_perm new_owner
            new_perm=$(stat -c '%a' "$target_dir" 2>/dev/null || stat -f '%Lp' "$target_dir" 2>/dev/null)
            new_owner=$(stat -c '%U:%G' "$target_dir" 2>/dev/null || stat -f '%Su:%Sg' "$target_dir" 2>/dev/null)
            
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_bai}[${gl_huang}修改后${gl_bai}]"
            echo -e "  ${gl_bai}目录: ${gl_bufan}$target_dir${gl_bai}"
            echo -e "  ${gl_bai}权限: ${gl_huang}$new_perm ($(stat -c '%A' "$target_dir" 2>/dev/null || stat -f '%Sp' "$target_dir" 2>/dev/null))"
            echo -e "  ${gl_bai}所有者: ${gl_lv}$new_owner${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            break_end
        else
            echo -e "${gl_hong}✗ 修改失败 (可能需要root权限): $target_dir${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            exit_animation    # 即将退出动画
        fi
    fi
    return 0
} 

compress_file_or_directory() {
    read -r -e -p "$(echo -e "${gl_bai}请输入要压缩的文件/目录名(${gl_huang}0${gl_bai}返回): ")" name

    [ -z "$name" ] && { cancel_empty "上一级选单"; return 1; }                   # break 或 continue 或 return ,视上下文而定
    [ "$name" = "0" ] && { cancel_return "文件管理器"; return 1; }   # break 或 continue 或 return ,视上下文而定
    
    if [ ! -e "$name" ]; then
        echo -e "${gl_bai}文件/目录 ${gl_lv}'$name' ${gl_bai}不存在"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    install tar
    tar -czvf "$name.tar.gz" "$name" && echo -e "${gl_lv}已压缩为 ${gl_huang}$name.tar.gz${gl_bai}" || echo -e "${gl_hong}压缩失败${gl_bai}"
}

rename_directory() {
    echo -e ""
    echo -e "${gl_zi}>>> 重命名目录${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    local dir_list=()
    if show_directory_list "." 4 false true "dir_list"; then
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        read -e -p "$(echo -e "${gl_bai}请输入目录序号或目录名(${gl_huang}0${gl_bai}返回): ")" input

        [ -z "$input" ] && { cancel_empty "上一级选单"; return 1; }                      # break 或 continue 或 return ,视上下文而定
        [ "$input" == "0" ] && { cancel_return "文件管理器"; return 1; }     # break 或 continue 或 return ,视上下文而定
        
        local current_name=""
        if [[ "$input" =~ ^[0-9]+$ ]] && [[ "$input" -ge 1 ]] && [[ "$input" -le ${#dir_list[@]} ]]; then
            current_name="${dir_list[$((input-1))]}"
        else
            current_name="$input"
        fi
        
        [[ ! -d "$current_name" ]] && { log_error "目录不存在: $current_name"; return 1; }
        
        read -e -p "$(echo -e "${gl_bai}请输入新目录名(${gl_huang}0${gl_bai}返回): ")" new_name
        [ -z "$new_name" ] && { cancel_empty "上一级选单"; return 1; }                           # break 或 continue 或 return ,视上下文而定
        [ "$new_name" == "0" ] && { cancel_return "文件管理器"; return 1; }          # break 或 continue 或 return ,视上下文而定
        [[ -e "$new_name" ]] && { log_error "目标已存在: $new_name"; return 1; }     # break 或 continue 或 return ,视上下文而定
        
        if mv "$current_name" "$new_name"; then
            echo -e "${gl_bai}目录已重命名: ${gl_huang}$current_name ${gl_bai}-> ${gl_lv}$new_name${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            break_end
        else
            echo -e "${gl_hong}重命名失败: ${gl_huang}$current_name${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            break_end
        fi
    fi
    return 0
}

delete_directories() {
    echo -e ""
    echo -e "${gl_zi}>>> 删除目录${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    local dir_list=()
    if show_directory_list "." 4 false true "dir_list"; then
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_huang}提示: 可输入序号、路径,或多个(空格分隔)${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        read -e -p "$(echo -e "${gl_bai}请输入要删除的目录(${gl_huang}0${gl_bai}返回): ")" input

        [ -z "$input" ] && { cancel_empty "上一级选单"; return 1; }                      # break 或 continue 或 return ,视上下文而定
        [ "$input" == "0" ] && { cancel_return "文件管理器"; return 1; }     # break 或 continue 或 return ,视上下文而定
        
        local -a targets=()
        for item in $input; do
            if [[ "$item" =~ ^[0-9]+$ ]] && [[ "$item" -ge 1 ]] && [[ "$item" -le ${#dir_list[@]} ]]; then
                targets+=("${dir_list[$((item-1))]}")
            else
                targets+=("$item")
            fi
        done
        
        [[ ${#targets[@]} -eq 0 ]] && { log_warn "未指定有效目录"; return 1; }  # break 或 continue 或 return ,视上下文而定
        
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_huang}即将删除以下目录:${gl_bai}"
        for d in "${targets[@]}"; do echo "  - $d"; done
        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
        [ "$confirm" = "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
        case "$confirm" in
            [Yy])
                for dir in "${targets[@]}"; do
                    if [[ -d "$dir" ]]; then
                        rm -rf "$dir" && log_ok "已删除: $dir" || log_error "删除失败: $dir"
                        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                        break_end
                    else
                        log_warn "不存在: $dir"
                        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                        break_end
                    fi
                done
                ;;
            *)
                log_warn "已取消删除"
                ;;
        esac
    fi
    return 0
}

go_parent_directory() {
    if [[ "$(pwd)" != "/" ]]; then
        local current_path="$(pwd)"
        cd ..
        echo -e "${gl_lv}已返回上级目录: ${gl_huang}$(pwd) ${gl_bai}"
        exit_animation    # 即将退出动画
    else
        echo -e "${gl_huang}已经在根目录: ${gl_hong}/ ${gl_bai}"
        exit_animation    # 即将退出动画
    fi
}

search_dir_here() {
    local keyword
    local non_interactive=false

    [[ $# -gt 0 && "$1" == "search_dir_here" ]] && shift
    [[ $# -gt 0 ]] && {
        keyword="$*"
        non_interactive=true
    }

    while true; do
        if [[ "$non_interactive" == false ]]; then 

            check_directory_empty "." "${gl_huang}目录${gl_zi}模糊搜索" "true" || return

            clear
            echo -e ""
            echo -e "${gl_zi}>>> ${gl_huang}目录${gl_zi}模糊搜索${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "当前目录: ${gl_huang}$(pwd)${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            ls --color=auto -x
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            read -r -e -p "$(echo -e "${gl_bai}请输入搜索关键词 (${gl_huang}0${gl_bai}返回): ")" keyword

            [[ "$keyword" == "0" ]] && { cancel_return "上一级选单"; break; }    # break 或 continue 或 return ,视上下文而定

            [[ -z "$keyword" ]] && {
                log_error "关键词不能为空!"
                continue
            }
        fi

        local here
        here="$(pwd)"
        local found=0
        local search_results=()

        while IFS= read -r -d '' dir; do
            local base_dir="${dir##*/}"
            [[ "${base_dir,,}" == *"${keyword,,}"* ]] && search_results+=("$dir")
        done < <(find "$here" -type d -print0 2>/dev/null)

        local unique_results=()
        while IFS= read -r -d '' dir; do
            unique_results+=("$dir")
        done < <(printf "%s\0" "${search_results[@]}" | sort -uz)

        if [[ ${#unique_results[@]} -gt 0 ]]; then
            [[ "$non_interactive" == true ]] &&
                echo "找到 ${#unique_results[@]} 个匹配的目录:" ||
                log_ok "找到 ${#unique_results[@]} 个匹配的目录:"
            echo
            for dir in "${unique_results[@]}"; do
                local abs_path
                abs_path="$(readlink -f "$dir" 2>/dev/null || echo "$dir")"
                if [[ "$non_interactive" == true ]]; then
                    echo "$abs_path"
                else
                    echo -e "${gl_lv}${abs_path}${gl_bai}"
                    local dir_info=$(ls -ldh "$dir" 2>/dev/null)
                    local size=$(echo "$dir_info" | awk '{print $5}')
                    local time_info=$(ls -ld --time-style=long-iso "$dir" 2>/dev/null | awk '{print $6, $7}')
                    local permissions=$(echo "$dir_info" | awk '{print $1}')
                    echo -e "  ${gl_hui}权限: $permissions | 大小: $size | 修改: $time_info${gl_bai}"
                    echo
                fi
                ((found++))
            done
        else
            [[ "$non_interactive" == true ]] &&
                echo "未找到包含 \"${keyword}\" 的目录。" ||
                {
                    log_warn "未找到包含 \"${keyword}\" 的目录。"
                    echo
                    log_info "类似目录:"
                    find "$here" -type d -maxdepth 2 | head -10 | while read -r d; do echo -e "  ${gl_hui}$(basename "$d")${gl_bai}"; done
                }
        fi

        [[ "$non_interactive" == false ]] && echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        [[ "$non_interactive" == true ]] && break
        echo -e "${gl_lv}操作完成${gl_bai}"
        read -n 1 -s -r -p "$(echo -e "${gl_bai}按任意键继续搜索${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}")"
        echo
    done
}

find_large_directories() {
    echo -e ""
    echo -e "${gl_zi}>>> 查找当前目录中的大目录${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    du -h --max-depth=1 . 2>/dev/null | sort -hr | head -6
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

list_dir_colorful() {
    local show_hidden="${1:-0}"
    local user_cols="${2:-0}"
    local files=()
    local has_content=0
    local item
    
    declare -A type_color=(
        [dir]="${gl_bufan}"      # 目录
        [exe]="${gl_lv}"         # 可执行文件
        [link]="${gl_zi}"        # 软链接
        [archive]="${gl_hong}"   # 压缩包
        [image]="${gl_huang}"    # 图片
        [code]="${gl_lan}"       # 代码文件
        [text]="${gl_bai}"       # 普通文本
        [else]="${gl_hui}"       # 其他
    )
    
    if [[ "${show_hidden}" -eq 1 ]]; then
        while IFS= read -r item; do
            [[ -e "${item}" || -L "${item}" ]] && {
                files+=("${item}")
                has_content=1
            }
        done < <(ls -A 2>/dev/null)
    else
        for item in *; do
            [[ -e "${item}" || -L "${item}" ]] && {
                files+=("${item}")
                has_content=1
            }
        done 2>/dev/null
    fi
    
    echo -e "${gl_huang}>>> 当前目录文件列表:${gl_bai}(${gl_lv}$(pwd)${gl_bai})"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    if [[ ${has_content} -eq 0 ]]; then
        echo -e "${gl_huang}当前目录为空${gl_bai}"
        return 0
    fi
    
    local file_info=()
    local max_display_width=0
    
    for item in "${files[@]}"; do
        local color="" suffix=""
        
        if [[ -L "${item}" ]]; then
            color="${type_color[link]}"
            suffix="@"
        elif [[ -d "${item}" ]]; then
            color="${type_color[dir]}"
            suffix="/"
        elif [[ -x "${item}" ]]; then
            color="${type_color[exe]}"
            suffix="*"
        else
            local ext="${item##*.}"
            if [[ "${ext}" != "${item}" ]]; then
                case "${ext,,}" in
                    tar|gz|bz2|xz|zip|7z|rar|zst|tgz|tbz2|txz) 
                        color="${type_color[archive]}" ;;
                    jpg|jpeg|png|gif|bmp|webp|svg|ico|tiff|avif) 
                        color="${type_color[image]}" ;;
                    sh|py|pl|rb|go|cpp|c|h|hpp|js|ts|jsx|tsx|java|php|rs|swift|kt|lua|vim) 
                        color="${type_color[code]}" ;;
                    txt|md|log|conf|cfg|yml|yaml|json|xml|ini|csv|toml) 
                        color="${type_color[text]}" ;;
                    *) 
                        color="${type_color[else]}" ;;
                esac
            else
                if [[ -b "${item}" || -c "${item}" ]]; then
                    color="${type_color[else]}"
                else
                    color="${type_color[text]}"
                fi
            fi
        fi
        
        local display_str="${item}${suffix}"
        local display_width
        
        if command -v wc &>/dev/null; then
            display_width=$(printf "%s" "${display_str}" | wc -L 2>/dev/null || echo "${#display_str}")
        else
            display_width=${#display_str}
        fi
        
        (( display_width > max_display_width )) && max_display_width=${display_width}
        
        file_info+=("${item}" "${color}" "${suffix}" "${display_width}" "${display_str}")
    done
    
    local term_width
    term_width=$(tput cols 2>/dev/null || echo 80)
    
    local col_width=$((max_display_width + 4))
    
    local items_per_line
    if [[ ${user_cols} -gt 0 ]]; then
        items_per_line=${user_cols}
        local needed_width=$((items_per_line * col_width - 4))
        if (( needed_width > term_width )); then
            items_per_line=$(( (term_width + 4) / col_width ))
            (( items_per_line < 1 )) && items_per_line=1
        fi
    else
        items_per_line=$((term_width / col_width))
        (( items_per_line < 1 )) && items_per_line=1
    fi
    
    (( items_per_line > ${#files[@]} )) && items_per_line=${#files[@]}
    
    local total_items=${#files[@]}
    local rows=$(( (total_items + items_per_line - 1) / items_per_line ))
    
    local row col index idx_base file_name file_color file_suffix file_width padding
    
    for ((row = 0; row < rows; row++)); do
        for ((col = 0; col < items_per_line; col++)); do
            index=$((row * items_per_line + col))
            
            if ((index < total_items)); then
                idx_base=$((index * 5))
                file_name="${file_info[idx_base]}"
                file_color="${file_info[idx_base+1]}"
                file_suffix="${file_info[idx_base+2]}"
                file_width="${file_info[idx_base+3]}"
                
                padding=$((col_width - file_width))
                
                printf "%b%s%b" "${file_color}" "${file_name}${file_suffix}" "${gl_bai}"
                
                if ((col < items_per_line - 1 && index < total_items - 1)); then
                    printf "%*s" "${padding}" ""
                fi
            fi
        done
        echo
    done
    
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    local total=${#files[@]}
    local dir_count=0 file_count=0 link_count=0
    for item in "${files[@]}"; do
        if [[ -L "${item}" ]]; then
            ((link_count++))
        elif [[ -d "${item}" ]]; then
            ((dir_count++))
        else
            ((file_count++))
        fi
    done
    
    echo -e "${gl_bai}总计: ${gl_lv}${total}${gl_bai}${gl_bufan}目录: ${dir_count}${gl_bai}    文件: ${file_count}${gl_bai}    ${gl_zi}链接: ${link_count}${gl_bai}"
    
    if [[ ${user_cols} -gt 0 ]]; then
        echo -e "${gl_hui}布局: ${gl_lv}${rows}${gl_hui}${gl_huang}× ${gl_lv}${items_per_line}${gl_hui}${gl_bai}"
    else
        echo -e "${gl_hui}布局: ${gl_lv}${rows}${gl_hui}${gl_huang}× ${gl_lv}${items_per_line}${gl_hui} 列 (${gl_huang}自动计算${gl_hui})${gl_bai}"
    fi
    
    return 0
}

list_directory_sizes() {
    local target_path="${1:-$(pwd)}"  # 支持传参,默认当前目录
    
    if [ ! -d "$target_path" ]; then
        echo -e "${gl_hong}错误: 路径不存在: ${target_path}${gl_bai}"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    local original_path="$(pwd)"
    cd "$target_path" || {
        echo -e "${gl_hong}错误: 无法进入目录: ${target_path}${gl_bai}"
        exit_animation    # 即将退出动画
        return 1
    }

    display_storage_info "$target_path" true

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

create_new_file() {
    read -e -p "$(echo -e "${gl_bai}请输入要创建的文件名(${gl_huang}0${gl_bai}返回): ")" filename
    [ -z "$filename" ] && { cancel_empty "上一级选单"; return 1; }
    [ "$filename" == "0" ] && { cancel_return "文件管理器"; return 1; }
    touch "$filename" && echo -e "${gl_lv}文件已创建${gl_bai}" || echo -e "${gl_hong}创建失败${gl_bai}"
}

manage_backup_files_simple() {
    local target_func="${1:-linux_file}" # 若未传参则默认使用 linux_file
    
    while true; do
        clear
        echo -e ""
        echo -e "${gl_zi}>>> 常用目录管理 ${gl_bai}[${gl_huang}调用函数: ${gl_lv}${target_func}${gl_bai}]"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

        if [[ -d "/vol1/1000/compose" ]]; then
            echo -e "${gl_bufan}1.${gl_bai} ${gl_lv}/vol1/1000/compose${gl_bai}                       ${gl_bufan}[Compose 目录] ✔${gl_bai}"
        else
            echo -e "${gl_bufan}1.${gl_bai} ${gl_hui}/vol1/1000/compose${gl_bai}                       ${gl_huang}[Compose 目录] ✖${gl_bai}"
        fi

        if [[ -d "/vol2/1000/mydisk/Video" ]]; then
            echo -e "${gl_bufan}2.${gl_bai} ${gl_lv}/vol2/1000/mydisk/Video${gl_bai}                  ${gl_bufan}[飞牛视频目录] ✔${gl_bai}"
        else
            echo -e "${gl_bufan}2.${gl_bai} ${gl_hui}/vol2/1000/mydisk/Video${gl_bai}                  ${gl_huang}[飞牛视频目录] ✖${gl_bai}"
        fi

        if [[ -d "/vol2/1000/media" ]]; then
            echo -e "${gl_bufan}3.${gl_bai} ${gl_lv}/vol2/1000/media${gl_bai}                         ${gl_bufan}[飞牛影视目录] ✔${gl_bai}"
        else
            echo -e "${gl_bufan}3.${gl_bai} ${gl_hui}/vol2/1000/media${gl_bai}                         ${gl_huang}[飞牛影视目录] ✖${gl_bai}"
        fi

        if [[ -d "/vol2/1000" ]]; then
            echo -e "${gl_bufan}4.${gl_bai} ${gl_lv}/vol2/1000${gl_bai}                               ${gl_bufan}[飞牛常用目录] ✔${gl_bai}"
        else
            echo -e "${gl_bufan}4.${gl_bai} ${gl_hui}/vol2/1000${gl_bai}                               ${gl_huang}[飞牛常用目录] ✖${gl_bai}"
        fi

        if [[ -d "/vol1/1000/compose/random-pic-api/photos" ]]; then
            echo -e "${gl_bufan}5.${gl_bai} ${gl_lv}/vol1/1000/compose/random-pic-api/photos${gl_bai} ${gl_bufan}[随机壁纸目录] ✔${gl_bai}"
        else
            echo -e "${gl_bufan}5.${gl_bai} ${gl_hui}/vol1/1000/compose/random-pic-api/photos${gl_bai} ${gl_huang}[随机壁纸目录] ✖${gl_bai}"
        fi

        if [[ -d "/var/lib/vz/template/iso" ]]; then
            echo -e "${gl_bufan}6.${gl_bai} ${gl_lv}/var/lib/vz/template/iso${gl_bai}                 ${gl_bufan}[PVE 固件目录] ✔${gl_bai}"
        else
            echo -e "${gl_bufan}6.${gl_bai} ${gl_hui}/var/lib/vz/template/iso${gl_bai}                 ${gl_huang}[PVE 固件目录] ✖${gl_bai}"
        fi

        if [[ -d "/var/lib/vz/dump" ]]; then
            echo -e "${gl_bufan}7.${gl_bai} ${gl_lv}/var/lib/vz/dump${gl_bai}                         ${gl_bufan}[PVE 备份目录] ✔${gl_bai}"
        else
            echo -e "${gl_bufan}7.${gl_bai} ${gl_hui}/var/lib/vz/dump${gl_bai}                         ${gl_huang}[PVE 备份目录] ✖${gl_bai}"
        fi

        if [[ -d "/mnt/compose" ]]; then
            echo -e "${gl_bufan}8.${gl_bai} ${gl_lv}/mnt/compose${gl_bai}                             ${gl_bufan}[Docker  目录] ✔${gl_bai}"
        else
            echo -e "${gl_bufan}8.${gl_bai} ${gl_hui}/mnt/compose${gl_bai}                             ${gl_huang}[Docker  目录] ✖${gl_bai}"
        fi

        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_bufan}9.${gl_bai} 手动输入路径${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        read -r -e -p "$(echo -e "${gl_bai}请选择路径序号 (${gl_huang}0${gl_bai}返回): ")" pve_file

        case "$pve_file" in
        1)
            if [[ -d "/vol1/1000/compose" ]]; then
                cd "/vol1/1000/compose" && $target_func "." "Compose项目管理" "常用目录管理"
            else
                check_directory_empty "/vol1/1000/compose" "Compose项目管理" || continue
            fi
            ;;
        2)
            if [[ -d "/vol2/1000/mydisk/Video" ]]; then
                cd "/vol2/1000/mydisk/Video" && $target_func "/vol2/1000/mydisk/Video" "视频文件管理" "常用目录管理"
            else
                check_directory_empty "/vol2/1000/mydisk/Video" "视频文件管理" || continue
            fi
            ;;
        3)
            if [[ -d "/vol2/1000/media" ]]; then
                cd "/vol2/1000/media" && $target_func "." "飞牛 TV 目录管理" "常用目录管理"
            else
                check_directory_empty "/vol2/1000/media" "飞牛 TV 目录管理" || continue
            fi
            ;;
        4)
            if [[ -d "/vol2/1000" ]]; then
                cd "/vol2/1000" && $target_func "." "飞牛文件管理" "常用目录管理"
            else
                check_directory_empty "/vol2/1000" "飞牛文件管理" || continue
            fi
            ;;
        5)
            if [[ -d "/vol1/1000/compose/random-pic-api/photos" ]]; then
                cd "/vol1/1000/compose/random-pic-api/photos" && $target_func "." "随机壁纸待处理目录管理" "常用目录管理"
            else
                check_directory_empty "/vol1/1000/compose/random-pic-api/photos" "随机壁纸待处理目录管理" || continue
            fi
            ;;
        6)
            if [[ -d "/var/lib/vz/template/iso" ]]; then
                cd "/var/lib/vz/template/iso" && $target_func "." "PVE 固件目录管理" "常用目录管理"
            else
                check_directory_empty "/var/lib/vz/template/iso" "PVE 固件目录管理" || continue
            fi
            ;;
        7)
            if [[ -d "/var/lib/vz/dump" ]]; then
                cd "/var/lib/vz/dump" && $target_func "." "PVE 备份目录管理" "常用目录管理"
            else
                check_directory_empty "/var/lib/vz/dump" "PVE 备份目录管理" || continue
            fi
            ;;
        8)
            if [[ -d "/mnt/compose" ]]; then
                cd "/mnt/compose" && $target_func "/mnt/compose" "Compose项目管理" "常用目录管理"
            else
                check_directory_empty "/mnt/compose" "Compose项目管理" || continue
            fi
            ;;
        9)
            read -r -e -p "$(echo -e "${gl_bai}请输入要进入的目录路径: ")" custom_path
            if [[ -d "$custom_path" ]]; then
                cd "$custom_path" && $target_func "." "自定义目录管理" "常用目录管理"
            else
                check_directory_empty "$custom_path" "飞牛文件管理" || continue
            fi
            ;;
        0) cancel_return; return ;;
        *) handle_invalid_input ;;
        esac
    done
}

edit_file_with_nano() {

    check_directory_empty "." "编辑文件" "true" || return

    clear
    echo -e "${gl_huang}>>> 当前目录文件列表:${gl_bai}(${gl_lv}$(pwd)${gl_bai})"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    if ! list_files "." 0 4; then
        exit_animation    # 即将退出动画
        return 1
    fi
    
    if [[ ${#LIST_FILES_ARRAY[@]} -eq 0 ]] || [[ "$LIST_FILES_COUNT" -eq 0 ]]; then
        exit_animation    # 即将退出动画
        return 1
    fi
    
    echo ""
    echo -e "${gl_zi}>>> 编辑文件${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -r -e -p "$(echo -e "${gl_bai}请输入序号(${gl_huang}1${gl_bai}-${gl_lv}${LIST_FILES_COUNT}${gl_bai})或文件名(${gl_huang}0${gl_bai}返回): ")" user_input

    [ -z "$user_input" ] && { cancel_empty "上一级选单"; return 1; }                     # break 或 continue 或 return ,视上下文而定
    [ "$user_input" == "0" ] && { cancel_return "文件管理器"; return 1; }    # break 或 continue 或 return ,视上下文而定
    
    local target_file=""
    
    if [[ "$user_input" =~ ^[0-9]+$ ]]; then
        local idx=$((user_input - 1))
        if [[ $idx -ge 0 && $idx -lt ${#LIST_FILES_ARRAY[@]} ]]; then
            target_file="${LIST_FILES_ARRAY[$idx]}"
        else
            log_error "序号超出范围: $user_input (有效范围: 1-${LIST_FILES_COUNT})"
            exit_animation    # 即将退出动画
            return 1
        fi
    else
        target_file="$user_input"
    fi
    
    if [[ ! -f "$target_file" ]]; then
        log_error "文件不存在: $target_file"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    install nano
    nano "$target_file"
}

file_chmod() {
    local return_target="${1:-文件管理器}"  # 接收参数,默认值为"文件管理器"
    while :; do
        check_directory_empty "." "修改文件权限" || return
        clear
        
        if ! list_files "." 0 4; then
            exit_animation    # 即将退出动画
            return
        fi
        
        if [[ ${#LIST_FILES_ARRAY[@]} -eq 0 ]] || [[ "$LIST_FILES_COUNT" -eq 0 ]]; then
            exit_animation    # 即将退出动画
            return
        fi
        
        echo ""
        echo -e "${gl_zi}>>> 修改文件权限${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        
        read -r -e -p "$(echo -e "${gl_bai}请输入文件序号(${gl_huang}1${gl_bai}-${gl_lv}${LIST_FILES_COUNT}${gl_bai})或文件名(${gl_huang}0${gl_bai}返回): ")" user_input
        
        [ -z "$user_input" ] && { cancel_empty "重新输入"; continue; }                    # break 或 continue 或 return ,视上下文而定
        [ "$user_input" = "0" ] && { cancel_return "$return_target"; break; }            # break 或 continue 或 return ,视上下文而定
        
        local filename=""
        
        if [[ "$user_input" =~ ^[0-9]+$ ]]; then
            local idx=$((user_input - 1))
            if [[ $idx -ge 0 && $idx -lt ${#LIST_FILES_ARRAY[@]} ]]; then
                filename="${LIST_FILES_ARRAY[$idx]}"
            else
                log_error "序号超出范围: $user_input (有效范围: 1-${LIST_FILES_COUNT})"
                sleep_fractional 1
                continue
            fi
        else
            filename="${user_input/#\~/$HOME}"
        fi
        
        if [[ ! -e "$filename" ]]; then
            log_error "文件或目录不存在: $filename"
            exit_animation    # 即将退出动画
            continue
        fi
        
        local curr_oct=$(stat -c "%a" "$filename" 2>/dev/null || stat -f "%A" "$filename" 2>/dev/null)
        local curr_sym=$(stat -c "%A" "$filename" 2>/dev/null || stat -f "%Sp" "$filename" 2>/dev/null)
        
        echo ""
        echo -e "${gl_huang}>>> 当前权限信息${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_bai}文件: ${gl_huang}${filename}${gl_bai}"
        echo -e "${gl_bai}权限: ${gl_lv}${curr_sym}${gl_bai}  (${gl_huang}${curr_oct}${gl_bai})"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo ""
        
        local new_perm=""
        while :; do
            read -r -e -p "$(echo -e "${gl_bai}请输入新权限 (如 ${gl_huang}755${gl_bai}${gl_lv}+x${gl_bai}${gl_hui}u-w${gl_bai}等,${gl_hong}0${gl_bai}取消): ")" new_perm
            
            [[ "$new_perm" == "0" ]] && { echo -e "${gl_huang}已取消操作${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"; sleep_fractional 0.6; break 2; }
            [[ -z "$new_perm" ]] && { echo -e "${gl_huang}已取消操作${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"; sleep_fractional 0.6; break 2; }
            
            if [[ "$new_perm" =~ ^[0-7]{1,3}$ ]] || [[ "$new_perm" =~ ^[ugoa]*[+-=][rwxXstugo]+$ ]]; then
                break
            else
                log_error "输入格式错误!请重新输入(例如 644、755、+x、g-w 等)"
                sleep_fractional 0.5
            fi
        done
        
        echo ""
        if chmod "$new_perm" "$filename" 2>/dev/null; then
            sync
            local new_oct=$(stat -c "%a" "$filename" 2>/dev/null || stat -f "%A" "$filename" 2>/dev/null)
            local new_sym=$(stat -c "%A" "$filename" 2>/dev/null || stat -f "%Sp" "$filename" 2>/dev/null)
            
            log_ok "权限修改成功!"
            echo ""
            echo -e "${gl_lv}>>> 修改后权限${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_bai}文件: ${gl_huang}${filename}${gl_bai}"
            echo -e "${gl_bai}权限: ${gl_lv}${new_sym}${gl_bai}  (${gl_huang}${new_oct}${gl_bai})"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        else
            log_error "修改失败,请检查文件系统权限或输入格式"
        fi
        
        break_end
    done
}

rename_file_or_dir() {
    clear
    echo -e "${gl_huang}>>> 当前目录文件列表:${gl_bai}(${gl_lv}$(pwd)${gl_bai})"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    if ! list_files "." 0 4; then
        exit_animation    # 即将退出动画
        return 1
    fi
    
    if [[ ${#LIST_FILES_ARRAY[@]} -eq 0 ]] || [[ "$LIST_FILES_COUNT" -eq 0 ]]; then
        exit_animation    # 即将退出动画
        return 1
    fi
    
    local current_name=""
    local new_name=""
    local user_input=""
    
    echo ""
    echo -e "${gl_zi}>>> 重命名文件${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -r -e -p "$(echo -e "${gl_bai}输入序号选择文件,或直接输入文件名 (${gl_huang}0${gl_bai}返回): ")" user_input
    
    [ -z "$user_input" ] && { cancel_empty "上一级选单"; return 1; }                     # break 或 continue 或 return ,视上下文而定
    [ "$user_input" == "0" ] && { cancel_return "文件管理器"; return 1; }    # break 或 continue 或 return ,视上下文而定
    
    if [[ "$user_input" =~ ^[0-9]+$ ]]; then
        local idx=$((user_input - 1))
        if ((idx >= 0 && idx < LIST_FILES_COUNT)); then
            current_name="${LIST_FILES_ARRAY[$idx]}"
            log_ok "已选择 [$user_input]: $current_name"
        else
            log_error "无效的序号: $user_input (有效范围: 1-$LIST_FILES_COUNT)"
            exit_animation    # 即将退出动画
            return 1
        fi
    else
        current_name="$user_input"
        if [[ ! -e "$current_name" ]]; then
            log_error "文件不存在: $current_name"
            exit_animation    # 即将退出动画
            return 1
        fi
        log_ok "已指定文件: $current_name"
    fi
    
    if [[ ! -e "$current_name" ]]; then
        log_error "无法访问文件: $current_name"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    echo ""
    echo -e "${gl_bai}当前文件名: ${gl_huang}${gl_bai}$current_name${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -r -e -p "$(echo -e "${gl_bai}请输入新文件名: ")" new_name
    [ "$new_name" = "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
    
    if [[ -z "$new_name" ]]; then
        log_error "新文件名不能为空"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    if [[ -e "$new_name" ]]; then
        log_error "目标文件已存在: $new_name"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    if [[ "$current_name" == "$new_name" ]]; then
        log_warn "新旧文件名相同,无需重命名"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    echo ""
    echo -e "${gl_huang}即将重命名:${gl_bai}"
    echo -e "  ${gl_huang}$current_name${gl_bai} ${gl_abi}->${gl_bai} ${gl_lv}$new_name${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
    [ "$confirm" = "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定

    case "$confirm" in
        [Yy])
            if mv "$current_name" "$new_name"; then
                echo ""
                log_ok "文件重命名成功"
                echo -e "${gl_huang}  $current_name ${gl_bai}-> ${gl_lv}$new_name${gl_bai}"
            else
                log_error "重命名失败"
                exit_animation    # 即将退出动画
            fi
            ;;
        [Nn]|"")
            log_warn "已取消操作"
            exit_animation    # 即将退出动画
            ;;
        *) handle_y_n ;;        # 无效的输入,请输入(y或N)。
    esac
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

delete_files() {
    check_directory_empty "." "删除文件" "true" || return
    clear
    if ! list_files "." 0 4; then
        exit_animation    # 即将退出动画
        return 1
    fi
    
    if [[ ${#LIST_FILES_ARRAY[@]} -eq 0 ]] || [[ "$LIST_FILES_COUNT" -eq 0 ]]; then
        exit_animation    # 即将退出动画
        return 1
    fi
    
    echo ""
    echo -e "${gl_zi}>>> 删除文件${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    read -r -e -p "$(echo -e "${gl_bai}请输入文件序号(${gl_huang}1${gl_bai}-${gl_lv}${LIST_FILES_COUNT}${gl_bai})或文件名(${gl_huang}0${gl_bai}返回): ")" user_input
    
    [ -z "$user_input" ] && { cancel_empty "上一级选单"; return 1; }                     # break 或 continue 或 return ,视上下文而定
    [ "$user_input" == "0" ] && { cancel_return "文件管理器"; return 1; }    # break 或 continue 或 return ,视上下文而定
    
    local inputs=($user_input)
    local files_to_delete=()
    local invalid_inputs=()
    
    for input in "${inputs[@]}"; do
        local target_file=""
        
        if [[ "$input" =~ ^[0-9]+$ ]]; then
            local idx=$((input - 1))
            if [[ $idx -ge 0 && $idx -lt ${#LIST_FILES_ARRAY[@]} ]]; then
                target_file="${LIST_FILES_ARRAY[$idx]}"
            else
                invalid_inputs+=("$input(超出范围)")
                continue
            fi
        else
            target_file="${input/#\~/$HOME}"
        fi
        
        if [[ -e "$target_file" ]]; then
            if [[ -d "$target_file" ]]; then
                log_warn "跳过目录(请使用目录删除功能): $target_file"
                exit_animation    # 即将退出动画
            else
                files_to_delete+=("$target_file")
            fi
        else
            invalid_inputs+=("$input(不存在)")
        fi
    done
    
    if [[ ${#invalid_inputs[@]} -gt 0 ]]; then
        log_error "无效输入: ${invalid_inputs[*]}"
        exit_animation    # 即将退出动画
    fi
    
    if [[ ${#files_to_delete[@]} -eq 0 ]]; then
        log_warn "没有可删除的文件"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    echo ""
    echo -e "${gl_hong}>>> 待删除文件列表${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    local count=0
    for file in "${files_to_delete[@]}"; do
        ((count++))
        printf "${gl_bufan}%2d.${gl_bai} ${gl_hong}%s${gl_bai}\n" "$count" "$file"
    done
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    read -r -e -p "$(echo -e "${gl_bai}确认删除以上 ${gl_hong}${#files_to_delete[@]}${gl_bai} 个文件? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
    [ "$confirm" = "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
    
    if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
        log_info "已取消删除操作"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    echo ""
    local success_count=0
    local fail_count=0
    
    for file in "${files_to_delete[@]}"; do
        if rm -f "$file"; then
            log_info "已删除: ${gl_hong}$file${gl_bai}"
            ((success_count++))
        else
            log_error "删除失败: $file"
            ((fail_count++))
        fi
    done
    
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_lv}成功: $success_count${gl_bai}  ${gl_hong}失败: $fail_count${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

cat_view_file_content() {
    local return_target="${1:-文件管理器}"  # 接收参数,默认值为"文件管理器"

    check_directory_empty "." "预览文件内容" "true" || return

    clear
    
    if ! list_files "." 0 4; then
        exit_animation    # 即将退出动画
        return 1
    fi
    
    if [[ ${#LIST_FILES_ARRAY[@]} -eq 0 ]] || [[ "$LIST_FILES_COUNT" -eq 0 ]]; then
        exit_animation    # 即将退出动画
        return 1
    fi
    
    echo ""
    echo -e "${gl_zi}>>> 预览文件内容${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    read -r -e -p "$(echo -e "${gl_bai}请输入文件序号(${gl_huang}1${gl_bai}-${gl_lv}${LIST_FILES_COUNT}${gl_bai})或文件名(${gl_huang}0${gl_bai}返回): ")" user_input
    
    [ -z "$user_input" ] && { cancel_empty "上一级选单"; return 1; }                         # break 或 continue 或 return ,视上下文而定
    [ "$user_input" == "0" ] && { cancel_return "$return_target"; return 1; }   # break 或 continue 或 return ,视上下文而定
    
    local target_file=""
    
    if [[ "$user_input" =~ ^[0-9]+$ ]]; then
        local idx=$((user_input - 1))
        if [[ $idx -ge 0 && $idx -lt ${#LIST_FILES_ARRAY[@]} ]]; then
            target_file="${LIST_FILES_ARRAY[$idx]}"
        else
            log_error "序号超出范围: $user_input (有效范围: 1-${LIST_FILES_COUNT})"
            exit_animation    # 即将退出动画
            return 1
        fi
    else
        target_file="${user_input/#\~/$HOME}"
    fi
    
    if [[ ! -e "$target_file" ]]; then
        log_error "文件不存在: $target_file"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    if [[ -d "$target_file" ]]; then
        log_error "无法预览目录内容: $target_file"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    local file_size=$(stat -c%s "$target_file" 2>/dev/null || stat -f%z "$target_file" 2>/dev/null)
    
    clear
    echo -e "${gl_zi}>>> 文件内容: ${gl_huang}$target_file${gl_bai} (${gl_lv}$file_size${gl_bai} bytes)"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    cat "$target_file"
    
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

search_file_here() {
    local keyword
    local non_interactive=false

    if [[ $# -gt 0 ]]; then
        if [[ "${1:-}" == "search_file_here" ]]; then
            shift
        fi
        if [[ $# -gt 0 ]]; then
            keyword="$*"
            non_interactive=true
        fi
    fi

    while true; do
        if [[ "$non_interactive" == false ]]; then

            check_directory_empty "." "${gl_huang}文件${gl_zi}模糊搜索" "true" || return

            clear
            echo -e "${gl_huang}>>> 当前 ${gl_lv}$(pwd) ${gl_huang}目录内容:"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            if [ -z "$(ls -A)" ]; then
                echo -e "${gl_huang}当前目录为空${gl_bai}"
            else
                ls --color=auto -xa
            fi

            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e ""
            echo -e "${gl_zi}>>> ${gl_huang}文件${gl_zi}模糊搜索${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            read -r -e -p "$(echo -e "${gl_bai}请输入搜索关键词 (${gl_huang}0${gl_bai}返回): ")" keyword

            [[ "$keyword" == "0" ]] && { cancel_return "上一级选单"; break; }    # break 或 continue 或 return ,视上下文而定
            [[ -z "$keyword" ]] && { cancel_empty "上一级选单"; continue; }      # break 或 continue 或 return ,视上下文而定
        fi

        local here
        here="$(pwd)"
        local found=0

        if [[ "$non_interactive" == false ]]; then
            echo -e ""
            echo -e "${gl_huang}>>> 正在执行模糊搜索 \"${keyword}\" ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        fi

        local search_results=()

        while IFS= read -r -d '' file; do
            [[ -n "$file" ]] && search_results+=("$file")
        done < <(find "$here" -iname "*${keyword}*" -type f -print0 2>/dev/null)

        while IFS= read -r -d '' file; do
            if [[ -n "$file" ]] && [[ ! " ${search_results[@]} " =~ " ${file} " ]]; then
                search_results+=("$file")
            fi
        done < <(find "$here" -type f -iregex ".*${keyword}.*" -print0 2>/dev/null)

        if command -v ag &>/dev/null; then
            while IFS= read -r -d '' file; do
                file="${file#./}"
                if [[ -n "$file" ]] && [[ ! " ${search_results[@]} " =~ " ${file} " ]]; then
                    search_results+=("$file")
                fi
            done < <(cd "$here" && ag -l -g ".*${keyword}.*" . 2>/dev/null | tr '\n' '\0')
        fi

        local unique_results=()
        if [[ ${#search_results[@]} -gt 0 ]]; then
            while IFS= read -r -d '' file; do
                [[ -n "$file" ]] && unique_results+=("$file")
            done < <(printf "%s\0" "${search_results[@]}" | sort -uz)
        fi

        if [[ ${#unique_results[@]} -gt 0 ]]; then
            if [[ "$non_interactive" == true ]]; then
                echo "找到 ${#unique_results[@]} 个匹配的文件:"
            else
                log_ok "找到 ${#unique_results[@]} 个匹配的文件:"
            fi
            echo
            for file in "${unique_results[@]}"; do
                if [[ ! -f "$file" ]]; then
                    if [[ -f "$here/$file" ]]; then
                        file="$here/$file"
                    else
                        continue
                    fi
                fi

                local abs_path
                abs_path="$(readlink -f "$file" 2>/dev/null || echo "$file")"
                if [[ "$non_interactive" == true ]]; then
                    echo "$abs_path"
                else
                    echo -e "${gl_lv}${abs_path}${gl_bai}"

                    if [[ -r "$file" ]]; then
                        local file_info
                        file_info=$(ls -lh "$file" 2>/dev/null)
                        if [[ $? -eq 0 ]]; then
                            local size
                            size=$(echo "$file_info" | awk '{print $5}')
                            local time_info
                            time_info=$(ls -l --time-style=long-iso "$file" 2>/dev/null | awk 'NR==1 {print $6, $7}')
                            local permissions
                            permissions=$(ls -l "$file" 2>/dev/null | awk 'NR==1 {print $1}')

                            echo -e "  ${gl_hui}权限: $permissions | 大小: $size | 修改: $time_info${gl_bai}"

                            if file "$file" 2>/dev/null | grep -q "text"; then
                                local preview
                                preview=$(head -1 "$file" 2>/dev/null | cut -c-50)
                                if [[ -n "$preview" ]]; then
                                    echo -e "  ${gl_zi}预览: ${preview}${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
                                fi
                            fi
                        else
                            echo -e "  ${gl_hui}[无法获取文件信息]${gl_bai}"
                        fi
                    else
                        echo -e "  ${gl_hui}[无法读取文件详细信息]${gl_bai}"
                    fi
                    echo
                fi
                ((found++))
            done
        else
            if [[ "$non_interactive" == true ]]; then
                echo "未找到包含 \"${keyword}\" 的文件。"
            else
                log_warn "未找到包含 \"${keyword}\" 的文件。"
                log_info "搜索建议:"
                echo -e "  ${gl_hui}• 尝试不同的关键词"
                echo -e "  ${gl_hui}• 使用更通用的词汇"
                echo -e "  ${gl_hui}• 检查文件是否在其他位置${gl_bai}"

                log_info "当前目录下的文件:"
                find "$here" -maxdepth 1 -type f -name "*" | head -5 | while read -r similar; do
                    echo -e "  ${gl_hui}$(basename "$similar")${gl_bai}"
                done
            fi
        fi

        if [[ "$non_interactive" == false ]]; then
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        fi

        if [[ "$non_interactive" == true ]]; then
            break
        fi

        break_end
    done
}

find_large_files() {
    check_directory_empty "." "查找当前目录中的大文件" "true" || return
    echo -e ""
    echo -e "${gl_zi}>>> 查找当前目录中的大文件${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    find . -path ./proc -prune -o -path ./sys -prune -o -type f -exec du -b {} + 2>/dev/null | sort -nr | head -5 | numfmt --to=iec --field=1
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

create_file() {
    local file_name=${1:-}

    echo -e ""
    echo -e "${gl_zi}>>> 创建文件${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    if [[ -z $file_name ]]; then
        read -r -e -p "$(echo -e "${gl_bai}请输入文件名(${gl_huang}0${gl_bai}返回): ")" file_name || return
        [[ -z "$file_name" ]] && { cancel_empty "上一级选单"; return 1; }
        [[ "$file_name" == "0" ]] && { cancel_return "上一级选单"; return 1; }
    fi

    if [[ -e $file_name ]]; then
        echo -e "${gl_hong}文件已存在:$file_name${gl_bai}"
        local overwrite
        read -r -e -p "$(echo -e "${gl_bai}是否覆盖?(${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}${gl_huang}0${gl_bai}返回): ")" overwrite || return
        [[ "$overwrite" == "0" ]] && { cancel_return "上一级选单"; return 1; }
        [[ "$overwrite" != [yY] ]] && { echo -e "${gl_huang}已取消操作${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"; sleep_fractional 0.6; return; }
    fi

    echo -e "${gl_huang}将创建文件:$file_name${gl_bai}"
    echo -e "${gl_bufan}按回车键开始用 nano 编辑文件(${gl_huang}Ctrl+X${gl_bai}退出nano)${gl_bai}"
    read -r -n 1 -s  # 等待任意键继续

    local tmp line_count=0
    tmp=$(mktemp)

    if nano "$tmp"; then
        if [[ -s $tmp ]]; then
            line_count=$(wc -l < "$tmp" 2>/dev/null || echo 0)
            mv "$tmp" "$file_name"
            echo -e "${gl_huang}文件创建成功,共写入 $line_count${gl_bai}"
            [[ -s $file_name ]] && cat -n "$file_name"
        else
            touch "$file_name"
            echo -e "${gl_bufan}创建空文件完成${gl_bai}"
        fi
    else
        echo -e "${gl_hong}nano 编辑失败或已取消${gl_bai}"
        rm -f "$tmp"
        return
    fi

    if [[ $file_name =~ \.(sh|py|pl)$ ]]; then
        local add_exec
        echo -e ""
        read -r -e -p "$(echo -e "${gl_bai}检测到脚本文件,是否添加执行权限? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}${gl_huang}0${gl_bai}返回): ")" add_exec || return
        [[ "$add_exec" == "0" ]] && { echo -e "${gl_huang}已跳过权限设置${gl_bai}"; }
        [[ "$add_exec" == [yY] ]] && chmod +x "$file_name"
        new_oct=$(stat -c "%a" "$file_name")
        new_sym=$(stat -c "%A" "$file_name")
        echo -e ""
        log_ok "权限已修改!"
        echo -e ""
        echo -e "${gl_bai}修改后 ${gl_huang}${file_name}${gl_bai} 权限: ${gl_lv}${new_sym}${gl_bai}  (${gl_huang}${new_oct}${gl_bai})"
    fi

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end  # 假设这是一个自定义的暂停函数
}

extract_archive() {
    if ! command -v tar &> /dev/null; then
        install tar
    fi
    echo -e ""
    echo -e "${gl_zi}>>> 解压文件/目录${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    read -e -p "$(echo -e "${gl_bai}请输入要解压的文件名(${gl_lv}.tar.gz${gl_bai})(${gl_huang}0${gl_bai}返回): ")" filename

    [ -z "$filename" ] && { cancel_empty "上一级选单"; return 1; }
    [ "$filename" == "0" ] && { cancel_return "文件管理器"; return 1; }
    
    if [[ ! -f "$filename" ]]; then
        echo -e "${gl_hong}✗ 错误: 文件不存在: $filename${gl_bai}"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    if [[ ! "$filename" =~ \.(tar\.gz|tgz|tar)$ ]]; then
        echo -e "${gl_huang}⚠ 警告: 文件可能不是标准的 tar.gz/tgz/tar 格式${gl_bai}"
        read -r -e -p "$(echo -e "是否继续解压? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
        if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
            echo -e "${gl_huang}已取消操作${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
            exit_animation    # 即将退出动画
            return 1
        fi
    fi
    
    echo -e "${gl_bai}正在解压: ${gl_huang}$filename${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    if tar -xzvf "$filename"; then
        echo -e ""
        echo -e "${gl_lv}✓ 解压成功!${gl_bai}"
        
        echo -e "${gl_bai}解压内容:${gl_bai}"
        tar -tzf "$filename" 2>/dev/null | head -10 | while read -r line; do
            echo -e "  ${gl_lv}${gl_bai} $line"
        done
        local total_files=$(tar -tzf "$filename" 2>/dev/null | wc -l)
        if [[ $total_files -gt 10 ]]; then
            echo -e "  ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}$total_files 个文件/目录${gl_bai}"
        fi
    else
        echo -e ""
        echo -e "${gl_hong}✗ 解压失败${gl_bai}"
        echo -e "${gl_huang}可能原因:${gl_bai}"
        echo -e "  1. 文件损坏或不完整"
        echo -e "  2. 文件格式不正确(非 gzip 压缩的 tar 文件)"
        echo -e "  3. 权限不足(尝试使用 sudo)"
        echo -e "  4. 磁盘空间不足"
        echo -e "  5. 文件名包含特殊字符"
    fi
    
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
    return 0
}

interactive_compress() {
    if [[ -z "$TRASH_CMD" ]]; then
        install_trash
    fi

    while true; do
        clear
        echo -e "${gl_huang}>>> 当前${gl_bai}(${gl_lv}文件${gl_hong}/${gl_zi}目录${gl_bai})${gl_huang}列表:${gl_lv}$(pwd)${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

        local list=() item i choice target fmt_idx format
        local compress_extensions=("zip" "7z" "tar" "tar.gz" "tgz" "rar" "gz")

        for item in *; do
            [[ "$item" == .* ]] && continue

            [[ ! -e "$item" ]] && continue

            local is_compressed=0
            for ext in "${compress_extensions[@]}"; do
                if [[ "$item" == *".$ext" ]]; then
                    is_compressed=1
                    break
                fi
            done

            ((is_compressed == 0)) && list+=("$item")
        done

        for item in */; do
            if [[ -d "$item" && "$item" != .*/ && "$item" != "./" ]]; then
                item="${item%/}"
                local exists=0
                for existing in "${list[@]}"; do
                    [[ "$existing" == "$item" ]] && exists=1 && break
                done
                ((exists == 0)) && list+=("$item")
            fi
        done

        if ((${#list[@]} > 0)); then
            IFS=$'\n' list=($(sort <<<"${list[*]}"))
            unset IFS
        fi

        if ((${#list[@]} == 0)); then
            echo -e "${gl_huang}当前目录无可压缩的文件/目录${gl_bai}"
            exit_animation    # 即将退出动画
            return
        fi
        
        display_horizontal_list "${list[@]}"

        echo -e ""
        echo -e "${gl_zi}>>> 压缩模式${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        read -r -e -p "$(echo -e "${gl_bai}请输入序号选择,或手动输入${gl_bai}(${gl_lv}文件${gl_hong}/${gl_zi}目录${gl_bai}) (${gl_huang}0 ${gl_bai}返回): ")" choice

        if [[ -z "$choice" || "$choice" == "0" ]]; then
            return
        fi

        if [[ "$choice" =~ ^[0-9]+$ ]] && ((choice >= 1 && choice <= ${#list[@]})); then
            target="${list[$((choice - 1))]}"
        else
            target="$choice"
        fi

        [[ -e "$target" ]] || {
            echo -e "${gl_hong}错误:'$target' 不存在!${gl_bai}"
            echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
            read -r -n1 -s
            continue
        }

        echo -e ""
        echo -e "${gl_huang}请选择压缩格式:${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_huang}1.${gl_bai} zip (通用)      ${gl_huang}2.${gl_bai} 7z (高压缩率)"
        echo -e "${gl_huang}3.${gl_bai} tar.gz (平衡)  ${gl_huang}4.${gl_bai} tar (仅打包)"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

        safe_read "请输入你的选择: " fmt_idx "number"

        case "$fmt_idx" in
        1) format="zip" ;;
        2) format="7z" ;;
        3) format="tar.gz" ;;
        4) format="tar" ;;
        *)
            echo -e "${gl_hong}无效序号!${gl_bai}"
            echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
            read -r -n1 -s
            continue
            ;;
        esac

        local output_dir
        read -r -e -p "$(echo -e "${gl_bai}输出目录 (${gl_huang}留空为当前目录${gl_bai}): ")" output_dir
        output_dir="${output_dir:-.}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e ""

        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        compress_file "$target" "$format" "$output_dir"

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

interactive_extract() {
    clear
    echo -e "${gl_zi}>>> 解压模式${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local list=() file i choice archive dest
    local extensions=("zip" "7z" "tar" "tar.gz" "tgz" "rar" "gz")
    
    list=()
    
    for ext in "${extensions[@]}"; do
        while IFS= read -r -d '' file; do
            [[ -n "$file" && -f "$file" ]] && {
                local exists=false
                for item in "${list[@]}"; do
                    [[ "$item" == "$file" ]] && { exists=true; break; }
                done
                [[ "$exists" == false ]] && list+=("$file")
            }
        done < <(find . -maxdepth 1 -type f -name "*.$ext" -print0 2>/dev/null)
    done

    if ((${#list[@]} == 0)); then
        log_warn "当前目录无压缩包文件"

        log_warn "正在检查无扩展名的压缩文件${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
        local file_count=0
        
        while IFS= read -r -d '' file; do
            [[ -f "$file" ]] && {
                if file "$file" 2>/dev/null | grep -qi "compressed\|archive\|zip\|gzip\|tar"; then
                    echo -e "${gl_huang}发现可能的压缩文件: $file${gl_bai}"
                    local exists=false
                    for item in "${list[@]}"; do
                        [[ "$item" == "$file" ]] && { exists=true; break; }
                    done
                    [[ "$exists" == false ]] && {
                        list+=("$file")
                        ((file_count++))
                    }
                fi
            }
        done < <(find . -maxdepth 1 -type f ! -name "*.*" -print0 2>/dev/null)

        if ((file_count == 0)); then
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_bai}按任意键返回${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
            read -r -n1 -s
            return
        fi
    fi

    if ((${#list[@]} > 0)); then
        IFS=$'\n' list=($(sort <<<"${list[*]}"))
        unset IFS
    fi

    echo -e "当前工作目录 ${gl_huang}$(pwd) ${gl_lv}可用的压缩包:${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local count=0
    local items_per_line=2
    local max_length=0

    for file in "${list[@]}"; do
        local len=${#file}
        ((len > max_length)) && max_length=$len
    done

    local term_width=$(tput cols 2>/dev/null || echo 80)
    if ((term_width > 120)); then
        items_per_line=4
    elif ((term_width > 80)); then
        items_per_line=3
    fi

    max_length=$((max_length + 4))

    for i in "${!list[@]}"; do
        count=$((count + 1))

        local file_ext="${list[i]##*.}"
        case "$file_ext" in
        zip | 7z)
            printf "${gl_huang}%2d.${gl_bai} ${gl_lv}%-${max_length}s${gl_bai}" "$count" "${list[i]}"
            ;;
        tar* | tgz)
            printf "${gl_huang}%2d.${gl_bai} ${gl_zi}%-${max_length}s${gl_bai}" "$count" "${list[i]}"
            ;;
        gz)
            printf "${gl_huang}%2d.${gl_bai} ${gl_lan}%-${max_length}s${gl_bai}" "$count" "${list[i]}"
            ;;
        *)
            printf "${gl_huang}%2d.${gl_bai} ${gl_bai}%-${max_length}s" "$count" "${list[i]}"
            ;;
        esac

        if ((count % items_per_line == 0)); then
            echo ""
        fi
    done

    ((count % items_per_line != 0)) && echo ""

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

    read -r -e -p "$(echo -e "${gl_bai}请输入序号选择,或手动输入文件名(${gl_huang}0 ${gl_bai}返回): ")" choice

    [[ -z "$choice" ]] && {
        echo -e "${gl_huang}已取消${gl_bai}"
        return
    }

    if [[ "$choice" =~ ^[0-9]+$ ]] && ((choice >= 1 && choice <= ${#list[@]})); then
        archive="${list[$((choice - 1))]}"
    else
        archive="$choice"
    fi

    [[ -f "$archive" ]] || {
        echo -e "${gl_hong}错误:'$archive' 不存在!${gl_bai}"
        return
    }

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -r -e -p "$(echo -e "${gl_bai}解压到目录 (${gl_huang}留空为当前目录${gl_bai}): ")" dest
    dest="${dest:-.}"

    if [[ ! -d "$dest" ]]; then
        echo -e "${gl_huang}目录 '$dest' 不存在,是否创建?(${gl_lv}y${gl_huang}/${gl_bai}N${gl_huang})${gl_bai}"
        read -r -n1 -s create_dir
        if [[ $create_dir =~ ^[Yy]$ ]]; then
            mkdir -p "$dest" && echo -e "${gl_lv}目录已创建${gl_bai}" || {
                echo -e "${gl_hong}创建目录失败!${gl_bai}"
                return
            }
        else
            dest="."
        fi
    fi

    extract_file "$archive" "$dest" "false"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

batch_extract_all() {
    clear
    echo -e "${gl_zi}>>> 批量解压模式${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}当前工作目录: ${gl_huang}$(pwd)${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local archives=()
    local archive dest_dir overwrite_all=false skip_all=false
    local extensions=("zip" "7z" "tar" "tar.gz" "tar.bz2" "tar.xz" "tgz" "tbz2" "txz" "rar" "gz" "bz2" "xz")

    for ext in "${extensions[@]}"; do
        for file in *."$ext"; do
            [[ -f "$file" ]] && archives+=("$file")
        done
    done

    for file in *; do
        [[ -f "$file" && ! "$file" =~ \. ]] && {
            if file "$file" | grep -qi "compressed\|archive\|zip\|gzip\|bzip2\|xz\|tar\|rar"; then
                archives+=("$file")
            fi
        }
    done

    archives=($(printf "%s\n" "${archives[@]}" | sort -u))
    local total=${#archives[@]}

    if [[ $total -eq 0 ]]; then
        log_warn "当前目录下没有找到压缩文件"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        exit_animation    # 即将退出动画
        return 1
    fi

    echo -e "${gl_lv}发现 ${gl_huang}$total${gl_lv} 个压缩文件:${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local count=0 max_length=0 items_per_line=2
    local term_width=$(tput cols 2>/dev/null || echo 80)

    for archive in "${archives[@]}"; do
        local len=${#archive}
        ((len > max_length)) && max_length=$len
    done

    if ((term_width > 120)); then
        items_per_line=4
    elif ((term_width > 80)); then
        items_per_line=3
    fi
    max_length=$((max_length + 4))

    for archive in "${archives[@]}"; do
        ((count++))
        local file_ext="${archive##*.}"
        local color="${gl_bai}"

        case "$file_ext" in
            zip|7z) color="${gl_lv}" ;;
            tar*|tgz|tbz2|txz) color="${gl_zi}" ;;
            gz|bz2|xz) color="${gl_lan}" ;;
            rar) color="${gl_hong}" ;;
        esac

        printf "${gl_huang}%2d.${gl_bai} ${color}%-${max_length}s${gl_bai}" "$count" "$archive"

        if ((count % items_per_line == 0)); then
            echo ""
        fi
    done
    ((count % items_per_line != 0)) && echo ""

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

    read -r -e -p "$(echo -e "${gl_bai}确认解压以上 ${gl_lv}$total${gl_bai} 个文件? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
    [[ ! "$confirm" =~ ^[Yy]$ ]] && {
        log_info "已取消解压操作"
        exit_animation    # 即将退出动画
        return 1
    }

    echo ""
    echo -e "${gl_bai}解压选项:${gl_bai}"
    echo -e "${gl_huang}1.${gl_bai} 解压到各自同名目录"
    echo -e "${gl_huang}2.${gl_bai} 全部解压到当前目录(推荐)"
    echo -e "${gl_huang}3.${gl_bai} 解压到指定目录"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    read -r -e -p "$(echo -e "${gl_bai}请选择解压方式(${gl_huang}默认${gl_lv}2${gl_bai}): ")" extract_mode
    [ "$extract_mode" = "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
    extract_mode="${extract_mode:-2}"

    local custom_dest=""
    if [[ "$extract_mode" == "3" ]]; then
        read -r -e -p "$(echo -e "${gl_bai}请输入目标目录路径: ")" custom_dest
        [ "$custom_dest" = "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
        custom_dest="${custom_dest/#\~/$HOME}"
        [[ -z "$custom_dest" ]] && custom_dest="."
        
        if [[ ! -d "$custom_dest" ]]; then
            read -r -e -p "$(echo -e "${gl_huang}目录不存在,是否创建? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_huang})${gl_bai}: ")" create_dir
            [ "$create_dir" = "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
            if [[ "$create_dir" =~ ^[Yy]$ ]]; then
                mkdir -p "$custom_dest" || {
                    log_error "创建目录失败: $custom_dest"
                    exit_animation    # 即将退出动画
                    return 1
                }
            else
                log_info "已取消"
                exit_animation    # 即将退出动画
                return 1
            fi
        fi
    fi

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

    local success=0 failed=0 skipped=0
    local i=0

    for archive in "${archives[@]}"; do
        ((i++))
        local archive_name=$(basename "$archive")
        local archive_base="${archive_name%.tar.gz}"  # 移除 .tar.gz 后缀
        archive_base="${archive_base%.tar.bz2}"
        archive_base="${archive_base%.tar.xz}"
        archive_base="${archive_base%.tgz}"
        archive_base="${archive_base%.tbz2}"
        archive_base="${archive_base%.txz}"
        archive_base="${archive_base%.zip}"
        archive_base="${archive_base%.7z}"
        archive_base="${archive_base%.rar}"
        archive_base="${archive_base%.tar}"
        archive_base="${archive_base%.gz}"
        archive_base="${archive_base%.bz2}"
        archive_base="${archive_base%.xz}"

        case "$extract_mode" in
            "1") dest_dir="./${archive_base}" ;;
            "2") dest_dir="." ;;
            "3") dest_dir="$custom_dest" ;;
            *) dest_dir="./${archive_base}" ;;
        esac

        echo -e "${gl_bai}[${gl_huang}$i${gl_bai}/${gl_lv}$total${gl_bai}] 正在解压: ${gl_huang}$archive_name${gl_bai}"

        if [[ "$dest_dir" != "." ]] && [[ -d "$dest_dir" ]]; then
            if [[ "$skip_all" == true ]]; then
                log_info "跳过(已存在): $archive_name"
                ((skipped++))
                continue
            elif [[ "$overwrite_all" == false ]]; then
                read -r -e -p "$(echo -e "${gl_huang}目录 '$dest_dir' 已存在,如何处理? (${gl_lv}o${gl_huang}覆盖/${gl_lv}s${gl_huang}跳过/${gl_lv}O${gl_huang}全部覆盖/${gl_lv}S${gl_huang}全部跳过): ")" action
                case "$action" in
                    [Oo]) ;;  # 覆盖,继续执行
                    [Ss])
                        log_info "跳过: $archive_name"
                        ((skipped++))
                        continue
                        ;;
                    "O"|"o")
                        overwrite_all=true
                        ;;
                    "S"|"s")
                        skip_all=true
                        ((skipped++))
                        continue
                        ;;
                esac
            fi
            
            if [[ "$overwrite_all" == true ]] || [[ "$action" =~ ^[Oo]$ ]]; then
                rm -rf "$dest_dir" 2>/dev/null || {
                    log_error "无法删除旧目录: $dest_dir"
                    ((failed++))
                    continue
                }
            fi
        fi

        if [[ "$dest_dir" != "." ]]; then
            mkdir -p "$dest_dir" || {
                log_error "创建目录失败: $dest_dir"
                ((failed++))
                continue
            }
        fi

        local result=0

        if [[ "$archive" == *.zip ]]; then
            if [[ "$dest_dir" == "." ]]; then
                unzip -o "$archive" >/dev/null 2>&1
            else
                unzip -o "$archive" -d "$dest_dir" >/dev/null 2>&1
            fi
            result=$?

        elif [[ "$archive" == *.7z ]]; then
            if [[ "$dest_dir" == "." ]]; then
                7z x "$archive" -y >/dev/null 2>&1
            else
                7z x "$archive" -o"$dest_dir" -y >/dev/null 2>&1
            fi
            result=$?

        elif [[ "$archive" == *.tar.gz ]] || [[ "$archive" == *.tgz ]]; then
            if [[ "$dest_dir" == "." ]]; then
                tar -xzf "$archive" >/dev/null 2>&1
            else
                tar -xzf "$archive" -C "$dest_dir" --strip-components=0 >/dev/null 2>&1
            fi
            result=$?

        elif [[ "$archive" == *.tar.bz2 ]] || [[ "$archive" == *.tbz2 ]]; then
            if [[ "$dest_dir" == "." ]]; then
                tar -xjf "$archive" >/dev/null 2>&1
            else
                tar -xjf "$archive" -C "$dest_dir" --strip-components=0 >/dev/null 2>&1
            fi
            result=$?

        elif [[ "$archive" == *.tar.xz ]] || [[ "$archive" == *.txz ]]; then
            if [[ "$dest_dir" == "." ]]; then
                tar -xJf "$archive" >/dev/null 2>&1
            else
                tar -xJf "$archive" -C "$dest_dir" --strip-components=0 >/dev/null 2>&1
            fi
            result=$?

        elif [[ "$archive" == *.tar ]]; then
            if [[ "$dest_dir" == "." ]]; then
                tar -xf "$archive" >/dev/null 2>&1
            else
                tar -xf "$archive" -C "$dest_dir" --strip-components=0 >/dev/null 2>&1
            fi
            result=$?

        elif [[ "$archive" == *.gz ]] && [[ "$archive" != *.tar.gz ]]; then
            local output_name="${archive%.gz}"
            [[ "$dest_dir" != "." ]] && output_name="$dest_dir/$(basename "$output_name")"
            gunzip -c "$archive" > "$output_name" 2>/dev/null
            result=$?

        elif [[ "$archive" == *.bz2 ]] && [[ "$archive" != *.tar.bz2 ]]; then
            local output_name="${archive%.bz2}"
            [[ "$dest_dir" != "." ]] && output_name="$dest_dir/$(basename "$output_name")"
            bunzip2 -c "$archive" > "$output_name" 2>/dev/null
            result=$?

        elif [[ "$archive" == *.xz ]] && [[ "$archive" != *.tar.xz ]]; then
            local output_name="${archive%.xz}"
            [[ "$dest_dir" != "." ]] && output_name="$dest_dir/$(basename "$output_name")"
            unxz -c "$archive" > "$output_name" 2>/dev/null
            result=$?

        elif [[ "$archive" == *.rar ]]; then
            if [[ "$dest_dir" == "." ]]; then
                unrar x -o+ "$archive" >/dev/null 2>&1
            else
                unrar x -o+ "$archive" "$dest_dir/" >/dev/null 2>&1
            fi
            result=$?

        else
            if [[ "$dest_dir" == "." ]]; then
                7z x "$archive" -y >/dev/null 2>&1
            else
                7z x "$archive" -o"$dest_dir" -y >/dev/null 2>&1
            fi
            result=$?
        fi

        if [[ $result -eq 0 ]]; then
            log_info "✓ 成功解压: ${gl_lv}$archive_name${gl_bai}${gl_huang}$dest_dir${gl_bai}"
            ((success++))
        else
            log_error "✗ 解压失败: ${gl_hong}$archive_name${gl_bai} (退出码: $result)"
            ((failed++))
        fi
    done

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_zi}批量解压完成!${gl_bai}"
    echo -e "${gl_lv}  成功: $success${gl_bai}  |  ${gl_hong}失败: $failed${gl_bai}  |  ${gl_huang}跳过: $skipped${gl_bai}  |  总计: $total${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    break_end
    return 0
}

compress_tool() {

    local install_only=false compress_file="" extract_file="" compress_format=""
    local output_dir="" auto_yes=false system_type=""

    setup_completion() {
        local current_word="${COMP_WORDS[COMP_CWORD]}"
        local previous_word="${COMP_WORDS[COMP_CWORD - 1]}"

        case "${previous_word}" in
        --compress | --extract)
            COMPREPLY=($(compgen -f -- "${current_word}"))
            ;;
        --format)
            local formats=("zip" "7z" "tar.gz" "tar")
            COMPREPLY=($(compgen -W "${formats[*]}" -- "${current_word}"))
            ;;
        --output)
            COMPREPLY=($(compgen -d -- "${current_word}"))
            ;;
        *)
            local options=("--install-only" "--compress" "--extract" "--format" "--output" "--auto-yes" "-h" "--help")
            COMPREPLY=($(compgen -W "${options[*]}" -- "${current_word}"))
            ;;
        esac
    }

    if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
        complete -F setup_completion compress_tool
    fi

    _detect_system() {
        if [[ -f /etc/os-release ]]; then
            source /etc/os-release
            echo "$ID"
        elif command -v lsb_release &>/dev/null; then
            lsb_release -si | tr '[:upper:]' '[:lower:]'
        else
            echo "unknown"
        fi
    }

    batch_compress_dirs() {
        clear
        echo -e "${gl_zi}>>> 批量压缩子目录${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_bai}当前工作目录: ${gl_huang}$(pwd)${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

        local dirs=()
        local dir

        for dir in */; do
            [[ -d "$dir" ]] && dirs+=("${dir%/}")
        done

        if ((${#dirs[@]} == 0)); then
            echo -e "${gl_hong}当前目录下没有子文件夹!${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_bai}按任意键返回${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
            read -r -n1 -s
            return
        fi

        echo -e "${gl_lv}发现以下子目录:${gl_bai}"
        local count=0
        for dir in "${dirs[@]}"; do
            ((count++))
            echo -e "${gl_huang}$count.${gl_bai} $dir"
        done
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

        echo -e "${gl_bai}请选择压缩格式:${gl_bai}"
        echo -e "${gl_huang}1.${gl_bai} zip        ${gl_huang}2.${gl_bai} tar.gz"
        echo -e "${gl_huang}3.${gl_bai} 7z         ${gl_huang}4.${gl_bai} tar"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        
        local format_choice compress_format compress_ext
        read -r -e -p "$(echo -e "${gl_bai}请输入格式序号(${gl_huang}默认1${gl_bai}): ")" format_choice
        format_choice="${format_choice:-1}"

        case "$format_choice" in
            1) compress_format="zip"; compress_ext="zip" ;;
            2) compress_format="tar.gz"; compress_ext="tar.gz" ;;
            3) compress_format="7z"; compress_ext="7z" ;;
            4) compress_format="tar"; compress_ext="tar" ;;
            *) compress_format="zip"; compress_ext="zip" ;;
        esac

        echo -e "${gl_lv}已选择格式: $compress_format${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

        read -r -e -p "$(echo -e "${gl_huang}确认压缩以上 ${gl_lv}$count${gl_huang} 个目录为 ${gl_lv}.$compress_ext${gl_huang} 格式? (${gl_lv}y${gl_huang}/${gl_bai}N${gl_huang})${gl_bai}: ")" confirm
        [[ ! "$confirm" =~ ^[Yy]$ ]] && {
            echo -e "${gl_huang}已取消${gl_bai}"
            return
        }

        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        local success=0 failed=0
        for dir in "${dirs[@]}"; do
            local output_name="${dir}.${compress_ext}"
            echo -e "${gl_bai}正在压缩: ${gl_huang}$dir${gl_bai}${gl_lv}$output_name${gl_bai}"
            
            case "$compress_format" in
                "zip")
                    zip -r "$output_name" "$dir" >/dev/null 2>&1 && ((success++)) || ((failed++))
                    ;;
                "tar")
                    tar -cvf "$output_name" "$dir" >/dev/null 2>&1 && ((success++)) || ((failed++))
                    ;;
                "tar.gz")
                    tar -czvf "$output_name" "$dir" >/dev/null 2>&1 && ((success++)) || ((failed++))
                    ;;
                "7z")
                    7z a "$output_name" "$dir" >/dev/null 2>&1 && ((success++)) || ((failed++))
                    ;;
            esac
        done

        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_lv}压缩完成!成功: $success, 失败: $failed${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        break_end
    }

    interactive_menu() {
        while true; do
            check_directory_empty "." "Linux压缩/解压工具" "true" || return

            clear
            echo -e ""
            echo -e "${gl_zi}安装依赖中${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            install zip 7zip gzip
            clear
            list_dir_colorful 0 4 # 当前目录列表
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e ""
            echo -e "${gl_zi}>>> Linux压缩/解压工具${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}7.  ${gl_bai}安全删除工具          ${gl_bufan}8.  ${gl_bai}文件回收站"
            echo -e "${gl_bufan}9.  ${gl_bai}批量压缩子目录        ${gl_bufan}10. ${gl_bai}批量解压模式"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_huang}0.  ${gl_bai}返回上一级选单        ${gl_hong}00. ${gl_bai}退出脚本"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            read -r -e -p "请输入你的选择: " choice
            case $choice in

            1)  interactive_compress ;;                             # 压缩文件/目录
            2)  interactive_extract ;;                              # 解压文件
            1)  enter_directory "Linux压缩/解压工具" ;;              # 进入指定目录
            4)  cd .. ;;                                            # 返回上一级目录
            5)  linux_file "." "文件管理工具" "Linux压缩/解压工具";;  # 文件管理工具
            6)  download_file ;;                                    # 文件下载工具
            7)  interactive_delete ;;                               # 安全删除工具
            8)  manage_trash_menu ;;                                # 文件回收站
            9)  batch_compress_dirs ;;                              # 批量压缩子目录(新增)
            10) batch_extract_all ;;                                # 批量解压模式
            0) cancel_return; return 0 ;;                           # 返回到上一级菜单
            00 | 000 | 0000) exit_script ;;                         # 感谢使用,再见!
            *) handle_invalid_input ;;                              # 无效的输入,请重新输入!
            esac
        done
    }

    while [[ $# -gt 0 ]]; do
        case ${1:-} in
        --install-only)
            install_only=true
            shift
            ;;
        --compress)
            compress_file="${2:-}"
            shift 2
            ;;
        --extract)
            extract_file="${2:-}"
            shift 2
            ;;
        --format)
            compress_format="${2:-}"
            shift 2
            ;;
        --output)
            output_dir="${2:-}"
            shift 2
            ;;
        --auto-yes)
            auto_yes=true
            shift
            ;;
        *)
            echo -e "${gl_hong}未知参数: $1${gl_bai}"
            return 1
            ;;
        esac
    done

    interactive_menu
}

batch_rename_files() {
    while true; do
        local current_dir=$(pwd)
        local files=()
        
        while IFS= read -r -d $'\0' file; do
            if [[ -f "$file" ]]; then
                files+=("$file")
            fi
        done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
        
        local file_count=${#files[@]}
        
        clear
        echo -e ""
        echo -e "${gl_zi}>>> 批量重命名文件${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        
        if [[ $file_count -eq 0 ]]; then
            echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
        else
            echo -e "${gl_bai}当前目录: ${gl_lv}${current_dir}${gl_bai}  ${gl_bai}文件数量: ${gl_lv}${file_count}${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            
            if [[ $file_count -le 20 ]]; then
                echo -e "${gl_bai}文件列表:${gl_bai}"
                for i in "${!files[@]}"; do
                    local file="${files[$i]}"
                    local filename=$(basename "$file")
                    echo -e "  ${gl_huang}$((i + 1))${gl_bai}. ${gl_bufan}${filename}${gl_bai}"
                done
            else
                echo -e "${gl_bai}显示前 20 个文件:${gl_bai}"
                for i in {0..19}; do
                    if [[ $i -lt $file_count ]]; then
                        local file="${files[$i]}"
                        local filename=$(basename "$file")
                        echo -e "  ${gl_huang}$((i + 1))${gl_bai}. ${gl_bufan}${filename}${gl_bai}"
                    fi
                done
                echo -e "  ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}还有 $((file_count - 20)) 个文件${gl_bai}"
            fi
        fi
        
        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}7.  ${gl_bai}删除所有空格"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_huang}0.  ${gl_bai}返回上一级选单        ${gl_hong}00. ${gl_bai}退出脚本"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        read -r -e -p "$(echo -e "${gl_bai}请选择重命名模式: ")" rename_mode

        case "$rename_mode" in
        1) rename_files_add_prefix ;;           # 添加前缀
        2) rename_files_add_suffix ;;           # 添加后缀
        3) rename_files_replace_string ;;       # 替换字符串
        4) rename_files_sequential ;;           # 序号重命名
        5) rename_files_change_case ;;          # 大小写转换
        6) rename_files_remove_chars ;;         # 移除字符
        7) rename_files_remove_spaces ;;        # 删除所有空格
        0) cancel_return; return ;;             # 返回到上一级菜单
        00 | 000 | 0000) exit_script ;;         # 感谢使用,再见!
        *) handle_invalid_input ;;              # 无效的输入,请重新输入!
        esac
    done
}

rename_files_add_prefix() {
    local current_dir=$(pwd)
    local files=()
    while IFS= read -r -d $'\0' file; do
        if [[ -f "$file" ]]; then
            files+=("$file")
        fi
    done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
    
    local file_count=${#files[@]}
    
    if [[ $file_count -eq 0 ]]; then
        echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
        exit_animation    # 即将退出动画
        return
    fi
    
    echo -e ""
    echo -e "${gl_zi}>>> 批量添加前缀${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -e -p "$(echo -e "${gl_bai}请输入要添加的前缀(${gl_huang}0${gl_bai}返回): ")" prefix
    if [[ -z "$prefix" ]]; then
        log_warn "前缀不能为空"
        exit_animation    # 即将退出动画
        return
    fi

    [ "$prefix" == "0" ] && { cancel_return "上一级选单"; return 1; }  # break 或 continue 或 return ,视上下文而定

    echo -e "${gl_bai}预览重命名结果:${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local rename_count=0
    local rename_files=()
    for file in "${files[@]}"; do
        local filename=$(basename "$file")
        local dir=$(dirname "$file")
        local newname="${dir}/${prefix}${filename}"

        if [[ "$filename" != "${prefix}${filename}" ]]; then
            rename_files+=("$file:$newname")
            echo -e "  ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}${prefix}${filename}${gl_bai}"
        fi
    done

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}将重命名 ${gl_lv}${#rename_files[@]}${gl_bai} 个文件${gl_bai}"

    if [[ ${#rename_files[@]} -gt 0 ]]; then
        read -r -e -p "$(echo -e "${gl_bai}确认执行重命名? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
        [ "$confirm" = "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
        case "$confirm" in
        [Yy])
            for rename_pair in "${rename_files[@]}"; do
                IFS=':' read -r old_name new_name <<<"$rename_pair"
                if mv "$old_name" "$new_name" 2>/dev/null; then
                    ((rename_count++))
                    log_info "已重命名: ${gl_bufan}$(basename "$old_name")${gl_bai} -> ${gl_lv}$(basename "$new_name")${gl_bai}"
                else
                    log_error "重命名失败: ${gl_bufan}$(basename "$old_name")${gl_bai}"
                fi
            done
            ;;
        [Nn])
            log_warn "操作已取消"
            ;;
        *) handle_y_n ;;        # 无效的输入,请输入(y或N)。
        esac
    else
        log_warn "没有文件需要重命名(可能文件已有相同前缀)"
    fi

    if [[ $rename_count -gt 0 ]]; then
        log_ok "成功重命名 ${rename_count} 个文件"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

rename_files_add_suffix() {
    local current_dir=$(pwd)
    local files=()
    while IFS= read -r -d $'\0' file; do
        if [[ -f "$file" ]]; then
            files+=("$file")
        fi
    done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
    
    local file_count=${#files[@]}
    
    if [[ $file_count -eq 0 ]]; then
        echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
        exit_animation    # 即将退出动画
        return
    fi
    
    echo -e ""
    echo -e "${gl_zi}>>> 批量添加后缀${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -e -p "$(echo -e "${gl_bai}请输入要添加的后缀 (不含扩展名)(${gl_huang}0${gl_bai}返回): ")" suffix
    if [[ -z "$suffix" ]]; then
        log_warn "后缀不能为空"
        exit_animation    # 即将退出动画
        return
    fi

    [[ "$suffix" == "0" ]] && { cancel_return "上一级选单"; return 1; }    # break 或 continue 或 return ,视上下文而定

    echo -e "${gl_bai}预览重命名结果:${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local rename_count=0
    local rename_files=()
    for file in "${files[@]}"; do
        local filename=$(basename "$file")
        local dir=$(dirname "$file")
        local newname

        if [[ "$filename" =~ \. ]]; then
            local ext="${filename##*.}"
            local name="${filename%.*}"
            if [[ "$name" == "$ext" ]]; then
                newname="${dir}/${filename}${suffix}"
            else
                newname="${dir}/${name}${suffix}.${ext}"
            fi
        else
            newname="${dir}/${filename}${suffix}"
        fi

        if [[ "$filename" != "$(basename "$newname")" ]]; then
            rename_files+=("$file:$newname")
            echo -e "  ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}$(basename "$newname")${gl_bai}"
        fi
    done

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}将重命名 ${gl_lv}${#rename_files[@]}${gl_bai} 个文件${gl_bai}"

    if [[ ${#rename_files[@]} -gt 0 ]]; then
        read -r -e -p "$(echo -e "${gl_bai}确认执行重命名? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
        case "$confirm" in
        [Yy])
            for rename_pair in "${rename_files[@]}"; do
                IFS=':' read -r old_name new_name <<<"$rename_pair"
                if mv "$old_name" "$new_name" 2>/dev/null; then
                    ((rename_count++))
                    log_info "已重命名: ${gl_bufan}$(basename "$old_name")${gl_bai} -> ${gl_lv}$(basename "$new_name")${gl_bai}"
                else
                    log_error "重命名失败: ${gl_bufan}$(basename "$old_name")${gl_bai}"
                fi
            done
            ;;
        [Nn])
            log_warn "操作已取消"
            ;;
        *) handle_y_n ;;        # 无效的输入,请输入(y或N)。
        esac
    else
        log_warn "没有文件需要重命名"
    fi

    if [[ $rename_count -gt 0 ]]; then
        log_ok "成功重命名 ${rename_count} 个文件"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

rename_files_replace_string() {
    local current_dir=$(pwd)
    local files=()
    while IFS= read -r -d $'\0' file; do
        if [[ -f "$file" ]]; then
            files+=("$file")
        fi
    done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
    
    local file_count=${#files[@]}
    
    if [[ $file_count -eq 0 ]]; then
        echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
        exit_animation    # 即将退出动画
        return
    fi
    
    echo -e ""
    echo -e "${gl_zi}>>> 替换字符${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -e -p "$(echo -e "${gl_bai}请输入要替换的字符串(${gl_huang}0${gl_bai}返回): ")" old_str

    [[ "$old_str" == "0" ]] && { cancel_return "上一级选单"; return 1; }

    if [[ -z "$old_str" ]]; then
        log_warn "要替换的字符串不能为空"
        exit_animation    # 即将退出动画
        return
    fi

    read -r -e -p "$(echo -e "${gl_bai}请输入替换为的字符串: ")" new_str
    [ "$new_str" == "0" ] && { cancel_return "上一级选单"; return 1; }   # break 或 continue 或 return ,视上下文而定

    echo -e "${gl_bai}预览重命名结果:${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local rename_count=0
    local rename_files=()
    for file in "${files[@]}"; do
        local filename=$(basename "$file")
        local dir=$(dirname "$file")
        local newname="${dir}/${filename//$old_str/$new_str}"

        if [[ "$filename" != "$(basename "$newname")" ]]; then
            rename_files+=("$file:$newname")
            echo -e "  ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}$(basename "$newname")${gl_bai}"
        fi
    done

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}将重命名 ${gl_lv}${#rename_files[@]}${gl_bai} 个文件${gl_bai}"

    if [[ ${#rename_files[@]} -gt 0 ]]; then
        read -r -e -p "$(echo -e "${gl_bai}确认执行重命名? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
        [ "$confirm" == "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
        case "$confirm" in
        [Yy])
            for rename_pair in "${rename_files[@]}"; do
                IFS=':' read -r old_name new_name <<<"$rename_pair"
                if mv "$old_name" "$new_name" 2>/dev/null; then
                    ((rename_count++))
                    log_info "已重命名: ${gl_bufan}$(basename "$old_name")${gl_bai} -> ${gl_lv}$(basename "$new_name")${gl_bai}"
                else
                    log_error "重命名失败: ${gl_bufan}$(basename "$old_name")${gl_bai}"
                fi
            done
            ;;
        [Nn])
            log_warn "操作已取消"
            ;;
        *) handle_y_n ;;        # 无效的输入,请输入(y或N)。
        esac
    else
        log_warn "没有找到匹配的字符串 '$old_str'"
    fi

    if [[ $rename_count -gt 0 ]]; then
        log_ok "成功重命名 ${rename_count} 个文件"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

rename_files_sequential() {
    local current_dir=$(pwd)
    local files=()
    while IFS= read -r -d $'\0' file; do
        if [[ -f "$file" ]]; then
            files+=("$file")
        fi
    done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
    
    local file_count=${#files[@]}
    
    if [[ $file_count -eq 0 ]]; then
        echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
        exit_animation    # 即将退出动画
        return
    fi
    
    echo -e ""
    echo -e "${gl_huang}>>> 序号重命名模板说明:${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "  ${gl_huang}###${gl_bai} 表示三位数字序号 (如: 001, 002)"
    echo -e "  ${gl_huang}##${gl_bai}  表示两位数字序号 (如: 01, 02)"
    echo -e "  ${gl_huang}#${gl_bai}   表示一位数字序号 (如: 1, 2)"
    echo -e "  ${gl_huang}%d${gl_bai}  表示数字序号 (如: 1, 2, 3)"
    echo -e ""
    echo -e "${gl_bai}示例:${gl_bai}"
    echo -e "  ${gl_huang}image-###.jpg${gl_bai}   -> ${gl_lv}image-001.jpg, image-002.jpg, ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo -e "  ${gl_huang}document_##.txt${gl_bai} -> ${gl_lv}document_01.txt, document_02.txt, ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo -e "  ${gl_huang}file_#.pdf${gl_bai}      -> ${gl_lv}file_1.pdf, file_2.pdf, ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    echo -e ""
    echo -e "${gl_zi}>>> 序号重命名${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -e -p "$(echo -e "${gl_bai}请输入文件名模板(${gl_huang}0${gl_bai}返回): ")" template
    [[ "$template" == "0" ]] && { cancel_return "上一级选单"; return 1; }

    if [[ -z "$template" ]]; then
        log_warn "模板不能为空"
        exit_animation    # 即将退出动画
        return
    fi

    echo -e "${gl_bai}预览重命名结果:${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local rename_count=0
    local rename_files=()
    local idx=1

    for file in "${files[@]}"; do
        local dir=$(dirname "$file")
        local filename=$(basename "$file")
        local ext="${filename##*.}"
        local name_without_ext="${filename%.*}"
        
        if [[ "$filename" =~ \. ]] && [[ "$name_without_ext" != "$ext" ]]; then
            local newname_template="${template%.*}"
            if [[ -z "$newname_template" ]]; then
                newname_template="$template"
            fi
            
            if [[ "$newname_template" =~ "###" ]]; then
                newname_template="${newname_template//###/$(printf "%03d" $idx)}"
            elif [[ "$newname_template" =~ "##" ]]; then
                newname_template="${newname_template//##/$(printf "%02d" $idx)}"
            elif [[ "$newname_template" =~ "#" ]]; then
                newname_template="${newname_template//#/$idx}"
            elif [[ "$newname_template" =~ "%d" ]]; then
                newname_template="${newname_template//%d/$idx}"
            else
                newname_template="${newname_template}_${idx}"
            fi
            
            local newname="${dir}/${newname_template}.${ext}"
        else
            local newname_template="$template"
            
            if [[ "$newname_template" =~ "###" ]]; then
                newname_template="${newname_template//###/$(printf "%03d" $idx)}"
            elif [[ "$newname_template" =~ "##" ]]; then
                newname_template="${newname_template//##/$(printf "%02d" $idx)}"
            elif [[ "$newname_template" =~ "#" ]]; then
                newname_template="${newname_template//#/$idx}"
            elif [[ "$newname_template" =~ "%d" ]]; then
                newname_template="${newname_template//%d/$idx}"
            else
                newname_template="${newname_template}_${idx}"
            fi
            
            local newname="${dir}/${newname_template}"
        fi
        
        rename_files+=("$file:$newname")
        echo -e "  ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}$(basename "$newname")${gl_bai}"
        ((idx++))
    done

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}将重命名 ${gl_lv}${#rename_files[@]}${gl_bai} 个文件${gl_bai}"

    if [[ ${#rename_files[@]} -gt 0 ]]; then
        read -r -e -p "$(echo -e "${gl_bai}确认执行重命名? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
        [ "$confirm" == "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
        case "$confirm" in
        [Yy])
            for rename_pair in "${rename_files[@]}"; do
                IFS=':' read -r old_name new_name <<<"$rename_pair"
                if mv "$old_name" "$new_name" 2>/dev/null; then
                    ((rename_count++))
                    log_info "已重命名: ${gl_bufan}$(basename "$old_name")${gl_bai} -> ${gl_lv}$(basename "$new_name")${gl_bai}"
                else
                    log_error "重命名失败: ${gl_bufan}$(basename "$old_name")${gl_bai}"
                fi
            done
            ;;
        [Nn])
            log_warn "操作已取消"
            ;;
        *) handle_y_n ;;        # 无效的输入,请输入(y或N)。
        esac
    fi

    if [[ $rename_count -gt 0 ]]; then
        log_ok "成功重命名 ${rename_count} 个文件"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

rename_files_change_case() {
    local current_dir=$(pwd)
    local files=()
    while IFS= read -r -d $'\0' file; do
        if [[ -f "$file" ]]; then
            files+=("$file")
        fi
    done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
    
    local file_count=${#files[@]}
    
    if [[ $file_count -eq 0 ]]; then
        echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
        exit_animation    # 即将退出动画
        return
    fi
    
    while true; do
        echo -e ""
        echo -e "${gl_zi}>>> 大小写转换${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}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_huang}0.  ${gl_bai}返回上一级选单        ${gl_hong}00. ${gl_bai}退出脚本"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        read -r -e -p "$(echo -e "${gl_bai}请选择转换模式: ")" case_mode

        case "$case_mode" in
        0) cancel_return;  return  ;;
        00 | 000 | 0000) exit_script ;; # 感谢使用,再见!
        1 | 2 | 3 | 4)
            local rename_count=0
            local rename_files=()

            echo -e "${gl_bai}预览重命名结果:${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

            for file in "${files[@]}"; do
                local filename=$(basename "$file")
                local dir=$(dirname "$file")
                local newname

                case "$case_mode" in
                1) # 转为小写
                    newname="${dir}/${filename,,}"
                    ;;
                2) # 转为大写
                    newname="${dir}/${filename^^}"
                    ;;
                3) # 首字母大写
                    newname="${dir}/${filename^}"
                    ;;
                4) # 单词首字母大写
                    newname="$filename"
                    if [[ "$newname" =~ [a-zA-Z] ]]; then
                        newname=$(echo "$newname" | sed -E 's/(^|_)([a-z])/\1\u\2/g' 2>/dev/null || echo "$newname")
                    fi
                    newname="${dir}/${newname}"
                    ;;
                esac

                if [[ "$filename" != "$(basename "$newname")" ]]; then
                    rename_files+=("$file:$newname")
                    echo -e "  ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}$(basename "$newname")${gl_bai}"
                fi
            done

            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_bai}将重命名 ${gl_lv}${#rename_files[@]}${gl_bai} 个文件${gl_bai}"

            if [[ ${#rename_files[@]} -gt 0 ]]; then
                read -r -e -p "$(echo -e "${gl_bai}确认执行重命名? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
                [ "$confirm" = "0" ] && { cancel_return "上一级选单"; continue; }      # break 或 continue 或 return ,视上下文而定
                case "$confirm" in
                [Yy])
                    for rename_pair in "${rename_files[@]}"; do
                        IFS=':' read -r old_name new_name <<<"$rename_pair"
                        if mv "$old_name" "$new_name" 2>/dev/null; then
                            ((rename_count++))
                            log_info "已重命名: ${gl_bufan}$(basename "$old_name")${gl_bai} -> ${gl_lv}$(basename "$new_name")${gl_bai}"
                        else
                            log_error "重命名失败: ${gl_bufan}$(basename "$old_name")${gl_bai}"
                        fi
                    done
                    ;;
                [Nn])
                    log_warn "操作已取消"
                    ;;
                *) handle_y_n ;;       # 无效的输入,请重新输入!
                esac
            else
                log_warn "没有文件需要转换大小写"
            fi

            if [[ $rename_count -gt 0 ]]; then
                log_ok "成功重命名 ${rename_count} 个文件"
            fi
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            break_end
            return
            ;;
        *) handle_invalid_input ;;
        esac
    done
}

rename_files_remove_chars() {
    local current_dir=$(pwd)
    local files=()
    while IFS= read -r -d $'\0' file; do
        if [[ -f "$file" ]]; then
            files+=("$file")
        fi
    done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
    
    local file_count=${#files[@]}
    
    if [[ $file_count -eq 0 ]]; then
        echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
        exit_animation    # 即将退出动画
        return
    fi
    
    echo -e ""
    echo -e "${gl_zi}>>> 移除字符${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -e -p "$(echo -e "${gl_bai}请输入要移除的字符或模式(${gl_huang}0${gl_bai}返回): ")" remove_pattern

    [[ "$remove_pattern" == "0" ]] && { cancel_return "上一级选单"; return 1; }    # break 或 continue 或 return ,视上下文而定

    if [[ -z "$remove_pattern" ]]; then
        log_warn "要移除的字符不能为空"
        exit_animation    # 即将退出动画
        return
    fi

    echo -e "${gl_bai}预览重命名结果:${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local rename_count=0
    local rename_files=()
    for file in "${files[@]}"; do
        local filename=$(basename "$file")
        local dir=$(dirname "$file")
        local newname="${dir}/${filename//$remove_pattern/}"

        if [[ "$filename" != "$(basename "$newname")" ]]; then
            rename_files+=("$file:$newname")
            echo -e "  ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}$(basename "$newname")${gl_bai}"
        fi
    done

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}将重命名 ${gl_lv}${#rename_files[@]}${gl_bai} 个文件${gl_bai}"

    if [[ ${#rename_files[@]} -gt 0 ]]; then
        read -r -e -p "$(echo -e "${gl_bai}确认执行重命名? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
        [[ "$confirm" == "0" ]] && { cancel_return "上一级选单"; return 1; }    # break 或 continue 或 return ,视上下文而定
        case "$confirm" in
        [Yy])
            for rename_pair in "${rename_files[@]}"; do
                IFS=':' read -r old_name new_name <<<"$rename_pair"
                if mv "$old_name" "$new_name" 2>/dev/null; then
                    ((rename_count++))
                    log_info "已重命名: ${gl_bufan}$(basename "$old_name")${gl_bai} -> ${gl_lv}$(basename "$new_name")${gl_bai}"
                else
                    log_error "重命名失败: ${gl_bufan}$(basename "$old_name")${gl_bai}"
                fi
            done
            ;;
        [Nn])
            log_warn "操作已取消"
            ;;
        *) handle_y_n ;;        # 无效的输入,请输入(y或N)。
        esac
    else
        log_warn "没有找到匹配的字符 '$remove_pattern'"
    fi

    if [[ $rename_count -gt 0 ]]; then
        log_ok "成功重命名 ${rename_count} 个文件"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

rename_files_remove_spaces() {
    local current_dir=$(pwd)
    local files=()
    while IFS= read -r -d $'\0' file; do
        if [[ -f "$file" ]]; then
            files+=("$file")
        fi
    done < <(find "$current_dir" -maxdepth 1 -type f -print0 2>/dev/null)
    
    local file_count=${#files[@]}
    
    if [[ $file_count -eq 0 ]]; then
        echo -e "${gl_huang}当前目录下没有找到任何文件${gl_bai}"
        exit_animation    # 即将退出动画
        return
    fi
    
    echo -e ""
    echo -e "${gl_zi}>>> 删除文件名中的所有空格${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    echo -e "${gl_bai}注意: 此操作将删除文件名中的所有空格字符${gl_bai}"
    echo -e "${gl_bai}包括文件名开头、中间和结尾的空格${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    echo -e "${gl_bai}预览重命名结果:${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local rename_count=0
    local rename_files=()
    for file in "${files[@]}"; do
        local filename=$(basename "$file")
        local dir=$(dirname "$file")
        local newname="${dir}/${filename// /}"

        if [[ "$filename" != "$(basename "$newname")" ]]; then
            rename_files+=("$file:$newname")
            echo -e "  ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}$(basename "$newname")${gl_bai}"
        fi
    done

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}将重命名 ${gl_lv}${#rename_files[@]}${gl_bai} 个文件${gl_bai}"

    if [[ ${#rename_files[@]} -gt 0 ]]; then
        read -r -e -p "$(echo -e "${gl_bai}确认执行重命名? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
        [[ "$confirm" == "0" ]] && { cancel_return "上一级选单"; return 1; }    # break 或 continue 或 return ,视上下文而定
        case "$confirm" in
        [Yy])
            for rename_pair in "${rename_files[@]}"; do
                IFS=':' read -r old_name new_name <<<"$rename_pair"
                if mv "$old_name" "$new_name" 2>/dev/null; then
                    ((rename_count++))
                    log_info "已重命名: ${gl_bufan}$(basename "$old_name")${gl_bai} -> ${gl_lv}$(basename "$new_name")${gl_bai}"
                else
                    log_error "重命名失败: ${gl_bufan}$(basename "$old_name")${gl_bai}"
                fi
            done
            ;;
        [Nn])
            log_warn "操作已取消"
            ;;
        *) handle_y_n ;;        # 无效的输入,请输入(y或N)。
        esac
    else
        log_warn "没有文件名包含空格"
    fi

    if [[ $rename_count -gt 0 ]]; then
        log_ok "成功重命名 ${rename_count} 个文件"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

download_single() {
    local url="${1:-}"
    [[ -z "$url" ]] && return 1 # 保险

    local raw_name=$(echo "$url" | sed 's/^.*\///' | sed 's/?.*$//')
    local filename=$(printf '%b' "${raw_name//%/\\x}" 2>/dev/null || echo "$raw_name")
    [[ -z "$filename" || "$filename" == "/" ]] && filename="downloaded_file"
    filename=$(echo "$filename" | tr -d '\000-\037' | tr '/' '_' | tr ':' '_' | tr '()[]{}<>' '_' | tr '*?&' '_')

    echo -e ""
    echo -e ""
    echo -e "${gl_huang}>>> 下载文件默认名称为: ${gl_lv}$filename${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -r -e -p "$(echo -e "${gl_bai}是否修改文件名?(${gl_huang}回车${gl_bai}使用默认名称): ")" new_filename
    [[ -n "$new_filename" ]] && filename="$new_filename"

    echo -e "${gl_bai}检测文件信息${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    local expected_size=0
    if command -v curl &>/dev/null; then
        expected_size=$(curl -s -L -I "$url" 2>/dev/null | grep -i 'content-length' | awk '{print $2}' | tr -d '\r' | tail -1)
    elif command -v wget &>/dev/null; then
        expected_size=$(wget --spider -S "$url" 2>&1 | grep -i 'content-length' | awk '{print $2}' | tail -1)
    fi
    [[ -n "$expected_size" && "$expected_size" -gt 0 ]] &&
        echo -e "${gl_bai}检测到文件大小: ${gl_lv}$(numfmt --to=iec "$expected_size")${gl_bai}" ||
        echo -e "${gl_huang}无法获取文件大小,将进行完整下载${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"

    local download_tool=""
    if command -v wget &>/dev/null; then
        download_tool="wget"
        echo -e ""
        echo -e "${gl_huang}使用 wget 下载${gl_bai}"
    elif command -v curl &>/dev/null; then
        download_tool="curl"
        echo -e ""
        echo -e "${gl_huang}使用 curl 下载${gl_bai}"
    else
        echo -e ""
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_hong}错误:未找到可用的下载工具 (wget/curl)${gl_bai}"
        read -n 1 -p "$(echo -e "按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} ")"
        return 1
    fi

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    local existing_size=0
    if [[ -f "$filename" ]]; then
        existing_size=$(stat -c%s "$filename" 2>/dev/null || echo 0)
        if [[ "$expected_size" -gt 0 && "$existing_size" -eq "$expected_size" ]]; then
            echo -e "${gl_lv}✓ 文件已存在且完整,无需下载。${gl_bai}"
            echo -e "${gl_lv}文件路径: ${gl_bai}$(realpath "$filename" 2>/dev/null || echo "$filename")"
            return 0
        elif [[ "$existing_size" -gt 0 ]]; then
            echo -e "${gl_huang}检测到已下载: ${gl_lv}$(numfmt --to=iec "$existing_size")${gl_huang},将尝试断点续传${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
        fi
    fi

    fmt_time() {
        local sec=$1
        local h=$((sec / 3600))
        local m=$(((sec % 3600) / 60))
        local s=$((sec % 60))
        printf "%02d:%02d:%02d" "$h" "$m" "$s"
    }
    local start_ts=$(date +%s)
    echo -e "${gl_lv}开始下载${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"

    local exit_code=0
    case $download_tool in
    wget)
        wget -c -T 30 --progress=bar:force:noscroll -O "$filename" "$url"
        exit_code=$?
        ;;
    curl)
        curl -L -C - --progress-bar -o "$filename" "$url"
        exit_code=$?
        ;;
    esac

    local end_ts=$(date +%s)
    local elapsed=$((end_ts - start_ts))
    echo -e "${gl_lv}下载耗时:${gl_bai}$(fmt_time "$elapsed")"

    [[ $exit_code -ne 0 ]] && echo -e "${gl_hong}下载失败!错误代码: $exit_code${gl_bai}" && return 1
    local actual_size=$(stat -c%s "$filename" 2>/dev/null || echo 0)
    if [[ "$expected_size" -gt 0 && "$actual_size" -ne "$expected_size" ]]; then
        echo -e "${gl_hong}文件大小不匹配,下载不完整!${gl_bai}"
        echo -e "${gl_hong}实际: ${gl_lv}$(numfmt --to=iec "$actual_size")${gl_hong},期望: ${gl_lv}$(numfmt --to=iec "$expected_size")${gl_bai}"
        read -n 1 -p "$(echo -e "${gl_hong}按任意键退出${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}")"
        return 1
    fi
    echo -e "${gl_lv}✓ 下载成功!文件大小完整。${gl_bai}"

    echo -e ""
    echo -e "${gl_huang}>>> 下载文件信息:${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    if [[ -f "$filename" ]]; then
        local file_path=$(realpath "$filename" 2>/dev/null || echo "$filename")
        local file_size_human
        file_size_human=$(stat -c %s "$filename" 2>/dev/null | numfmt --to=iec 2>/dev/null || echo "未知")
        local file_bytes=$(stat -c%s "$filename" 2>/dev/null || echo 0)
        local file_type=$(file -b "$filename" 2>/dev/null || echo "未知")
        local mod_time=$(stat -c "%y" "$filename" 2>/dev/null | cut -d'.' -f1 || echo "未知")
        local md5sum=$(md5sum "$filename" 2>/dev/null | cut -d' ' -f1 || echo "计算失败")

        echo -e "${gl_bai}文件路径: ${gl_lv}$file_path${gl_bai}"
        echo -e "${gl_bai}文件大小: ${gl_lv}$file_size_human (${file_bytes} 字节)${gl_bai}"
        [[ "$expected_size" -gt 0 ]] && echo -e "${gl_bai}完整性: ${gl_lv}✓ 完整${gl_bai}"
        echo -e "${gl_bai}文件类型: ${gl_lv}$file_type${gl_bai}"
        echo -e "${gl_bai}修改时间: ${gl_lv}$mod_time${gl_bai}"
        echo -e "${gl_bai}MD5 校验: ${gl_lv}$md5sum${gl_bai}"
    else
        echo -e "${gl_hong}错误:无法找到下载的文件${gl_bai}"
    fi
    return 0
}

download_file() {
    if [[ -n "${1:-}" ]]; then
        download_single "$1"
        return
    fi

    while true; do
        clear
        if [ -z "$(ls -A)" ]; then
            echo -e "${gl_huang}>>> 当前目录文件列表:${gl_bai}(${gl_lv}$(pwd)${gl_bai})"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_huang}当前目录为空${gl_bai}"
        else
            list_dir_colorful 0 4
        fi
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e ""
        echo -e "${gl_zi}>>> 文件下载${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        read -r -e -p "$(echo -e "${gl_bai}请输入下载链接(${gl_huang}0${gl_bai}返回):")" url
        [ "$url" = "0" ] && { cancel_return; return 1; }
        [[ -z "$url" ]] && echo -e "${gl_hong}错误:链接不能为空!${gl_bai}" && read -n 1 -p "$(echo -e "按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} ")" && continue
        url=$(echo "$url" | sed 's|https://https://|https://|g')

        if [[ ! "$url" =~ ^https?:// ]]; then
            echo -e "${gl_hong}错误:链接必须以http://或https://开头!${gl_bai}"
            exit_animation    # 即将退出动画
            continue
        fi

        download_single "$url"

        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_lv}✓ 下载成功!${gl_bai}"
        read -r -n 1 -p "$(echo -e "${gl_bai}按任意键继续下载${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}")"
    done
}

move_file_or_directory() {

    check_directory_empty "." "移动文件或目录" "true" || return

    clear
    
    if ! list_files "." 0 4; then
        exit_animation    # 即将退出动画
        return 1
    fi
    
    if [[ ${#LIST_FILES_ARRAY[@]} -eq 0 ]] || [[ "$LIST_FILES_COUNT" -eq 0 ]]; then
        exit_animation    # 即将退出动画
        return 1
    fi
    
    echo ""
    echo -e "${gl_zi}>>> 移动文件或目录${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}提示: 支持输入序号、完整路径或通配符模式(${gl_lv}如 *.tar.gz${gl_bai})${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    read -r -e -p "$(echo -e "${gl_bai}请输入源文件序号(${gl_huang}1${gl_bai}-${gl_lv}${LIST_FILES_COUNT}${gl_bai})、路径或通配符(${gl_huang}0${gl_bai}返回): ")" src_input
    
    [ -z "$src_input" ] && { cancel_empty "上一级选单"; return 1; }                      # break 或 continue 或 return ,视上下文而定
    [ "$src_input" == "0" ] && { cancel_return "文件管理器"; return 1; }     # break 或 continue 或 return ,视上下文而定
    
    local src_paths=()  # 改为数组,支持多文件
    
    if [[ "$src_input" =~ ^[0-9]+$ ]]; then
        local idx=$((src_input - 1))
        if [[ $idx -ge 0 && $idx -lt ${#LIST_FILES_ARRAY[@]} ]]; then
            src_paths=("${LIST_FILES_ARRAY[$idx]}")
        else
            log_error "序号超出范围: $src_input (有效范围: 1-${LIST_FILES_COUNT})"
            exit_animation    # 即将退出动画
            return 1
        fi
    elif [[ "$src_input" == *"*"* ]] || [[ "$src_input" == *"?"* ]] || [[ "$src_input" == *"["* ]]; then
        local pattern="${src_input/#\~/$HOME}"
        
        local matched_files=()
        local file
        for file in $pattern; do
            [[ -e "$file" ]] && matched_files+=("$file")
        done
        
        if [[ ${#matched_files[@]} -eq 0 ]]; then
            log_error "未找到匹配的文件: $src_input"
            exit_animation    # 即将退出动画
            return 1
        fi
        
        echo -e ""
        echo -e "${gl_lv}找到 ${gl_huang}${#matched_files[@]}${gl_lv} 个匹配文件:${gl_bai}"
        local count=0
        for file in "${matched_files[@]}"; do
            ((count++))
            printf "${gl_huang}%2d.${gl_bai} ${gl_bai}%-30s${gl_bai}" "$count" "$(basename "$file")"
            if ((count % 2 == 0)); then
                echo ""
            fi
        done
        if ((count % 2 != 0)); then
            echo ""
        fi
        echo ""
        
        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
        [ "$confirm" == "0" ] && { cancel_return "文件管理器"; return 1; }      # break 或 continue 或 return ,视上下文而定
        if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
            log_info "已取消移动操作"
            exit_animation    # 即将退出动画
            return 1
        fi
        
        src_paths=("${matched_files[@]}")
    else
        local manual_path="${src_input/#\~/$HOME}"
        if [[ -e "$manual_path" ]]; then
            src_paths=("$manual_path")
        else
            log_error "文件或目录不存在: $manual_path"
            exit_animation    # 即将退出动画
            return 1
        fi
    fi
    
    echo ""
    echo -e "${gl_huang}>>> 选择目标位置${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    local dir_array=()
    local dir_count=0
    local i item item_path
    for i in "${!LIST_FILES_ARRAY[@]}"; do
        item="${LIST_FILES_ARRAY[$i]}"
        item_path="./$item"
        if [[ -d "$item_path" ]]; then
            dir_array[$dir_count]="$item"
            ((dir_count++))
        fi
    done
    
    if [[ $dir_count -gt 0 ]]; then
        echo -e "${gl_bufan}当前目录中的子目录:${gl_bai}"
        local count=0
        for ((i=0; i<dir_count; i++)); do
            ((count++))
            printf "${gl_bufan}%2d.${gl_bai} ${gl_zi}%-20s${gl_bai}" "$count" "${dir_array[$i]}"
            if ((count % 2 == 0)); then
                echo ""
            fi
        done
        if ((count % 2 != 0)); then
            echo ""
        fi
        echo ""
    fi
    
    read -r -e -p "$(echo -e "${gl_bai}请输入目标路径 (目录序号、目录名或完整路径)(${gl_huang}0${gl_bai}返回): ")" dest_input

    [ -z "$dest_input" ] && { cancel_empty "上一级选单"; return 1; }                     # break 或 continue 或 return ,视上下文而定
    [ "$dest_input" == "0" ] && { cancel_return "文件管理器"; return 1; }    # break 或 continue 或 return ,视上下文而定
    
    local dest_path=""
    
    if [[ "$dest_input" =~ ^[0-9]+$ ]]; then
        local idx=$((dest_input - 1))
        if [[ $idx -ge 0 && $idx -lt $dir_count ]]; then
            dest_path="${dir_array[$idx]}"
        else
            log_error "目录序号超出范围: $dest_input"
            exit_animation    # 即将退出动画
            return 1
        fi
    else
        dest_path="${dest_input/#\~/$HOME}"
    fi
    
    if [[ ! -d "$dest_path" ]]; then
        if [[ -e "$dest_path" ]]; then
            log_error "目标必须是目录: $dest_path"
            exit_animation    # 即将退出动画
            return 1
        else
            read -r -e -p "$(echo -e "${gl_bai}目标目录不存在,是否创建? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" create_confirm
            [ "$create_confirm" = "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
            if [[ "$create_confirm" =~ ^[Yy]$ ]]; then
                if ! mkdir -p "$dest_path"; then
                    log_error "创建目录失败: $dest_path"
                    exit_animation    # 即将退出动画
                    return 1
                fi
                log_info "已创建目录: $dest_path"
            else
                log_info "已取消移动操作"
                exit_animation    # 即将退出动画
                return 1
            fi
        fi
    fi
    
    [[ "$dest_path" != */ ]] && dest_path="$dest_path/"
    
    local success_count=0
    local fail_count=0
    local src_path src_basename dest_full_path
    
    for src_path in "${src_paths[@]}"; do
        src_basename=$(basename "$src_path")
        dest_full_path="${dest_path}${src_basename}"
        
        if [[ -e "$dest_full_path" ]]; then
            read -r -e -p "$(echo -e "${gl_bai}目标已存在 '${gl_huang}$src_basename${gl_bai}',是否覆盖? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}/${gl_huang}a${gl_bai}全部): ")" confirm
            [ "$confirm" = "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
            case "$confirm" in
                [Aa])  # 全部覆盖,不再询问
                    ;;
                [Yy])  # 单个覆盖
                    ;;
                *)     # 跳过
                    log_info "跳过: $src_basename"
                    ((fail_count++))
                    continue
                    ;;
            esac
        fi
        
        if mv "$src_path" "$dest_full_path"; then
            log_info "成功移动: ${gl_huang}$src_basename${gl_bai}"
            ((success_count++))
        else
            log_error "移动失败: ${gl_huang}$src_basename${gl_bai}"
            ((fail_count++))
        fi
    done
    
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    if [[ ${#src_paths[@]} -gt 1 ]]; then
        log_info "批量移动完成: 成功 ${gl_lv}$success_count${gl_bai}, 失败 ${gl_hong}$fail_count${gl_bai}, 总计 ${gl_huang}${#src_paths[@]}${gl_bai}"
    else
        log_info "移动完成: ${gl_lv}$success_count${gl_bai} 成功, ${gl_hong}$fail_count${gl_bai} 失败"
    fi
    
    break_end 
    return 0
}

copy_file_or_directory() {
    check_directory_empty "." "复制文件/目录" "true" || return
    clear

    if ! list_files "." 0 4; then
        exit_animation    # 即将退出动画
        return 1
    fi
    
    if [[ ${#LIST_FILES_ARRAY[@]} -eq 0 ]] || [[ "$LIST_FILES_COUNT" -eq 0 ]]; then
        exit_animation    # 即将退出动画
        return 1
    fi
    
    local src_path=""
    local dest_path=""
    local user_input=""
    local src_name=""
    
    echo ""
    echo -e "${gl_zi}>>> 复制文件/目录${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -r -e -p "$(echo -e "${gl_bai}输入序号选择源文件/目录,或直接输入路径 (${gl_huang}0${gl_bai}返回): ")" user_input
    
    [[ -z "$user_input" ]] && { cancel_empty "上一级选单"; return 1; }                       # break 或 continue 或 return ,视上下文而定
    [[ "$user_input" == "0" ]] && { cancel_return "文件管理器"; return 1; }      # break 或 continue 或 return ,视上下文而定
    
    if [[ "$user_input" =~ ^[0-9]+$ ]]; then
        local idx=$((user_input - 1))
        if ((idx >= 0 && idx < LIST_FILES_COUNT)); then
            src_path="${LIST_FILES_ARRAY[$idx]}"
            log_ok "已选择 [$user_input]: $src_path"
        else
            log_error "无效的序号: $user_input (有效范围: 1-$LIST_FILES_COUNT)"
            exit_animation    # 即将退出动画
            return 1
        fi
    else
        src_path="$user_input"
        if [[ ! -e "$src_path" ]]; then
            log_error "文件或目录不存在: $src_path"
            exit_animation    # 即将退出动画
            return 1
        fi
        log_ok "已指定: $src_path"
    fi
    
    if [[ ! -e "$src_path" ]]; then
        log_error "无法访问: $src_path"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    src_name=$(basename "$src_path")
    
    echo ""
    echo -e "${gl_bai}源路径: ${gl_huang}$src_path${gl_bai}"
    if [[ -d "$src_path" ]]; then
        echo -e "${gl_bai}类型: ${gl_zi}目录${gl_bai}"
    else
        echo -e "${gl_bai}类型: ${gl_lv}文件${gl_bai}"
        local file_size=$(du -h "$src_path" 2>/dev/null | cut -f1)
        echo -e "${gl_bai}大小: ${gl_huang}$file_size${gl_bai}"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    read -r -e -p "$(echo -e "${gl_bai}请输入目标路径 (包括新文件名或目录名)(${gl_huang}0${gl_bai}返回)")" dest_path

    [[ "$dest_path" == "0" ]] && { cancel_return "文件管理器"; return 1; }
    
    if [[ -z "$dest_path" ]]; then
        log_error "目标路径不能为空"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    if [[ -e "$dest_path" ]]; then
        if [[ -d "$dest_path" ]]; then
            dest_path="${dest_path%/}/$src_name"
            log_info "目标为目录,自动调整为: $dest_path"
        else
            log_warn "目标文件已存在: $dest_path"
            read -r -e -p "$(echo -e "${gl_bai}是否覆盖? (${gl_hong}y${gl_bai}/${gl_lv}N${gl_bai}): ")" overwrite
            if [[ ! "$overwrite" =~ ^[Yy]$ ]]; then
                log_info "已取消操作"
                exit_animation    # 即将退出动画
                return 1
            fi
        fi
    fi
    
    echo ""
    echo -e "${gl_huang}即将复制:${gl_bai}"
    echo -e "  ${gl_huang}$src_path${gl_bai}"
    echo -e "${gl_bai}到:${gl_bai}"
    echo -e "  ${gl_lv}$dest_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
    [[ "$confirm" == "0" ]] && { cancel_return "文件管理器"; return 1; }      # break 或 continue 或 return ,视上下文而定
    
    case "$confirm" in
        [Yy])
            if cp -r "$src_path" "$dest_path"; then
                echo ""
                log_ok "复制成功"
                echo -e "${gl_huang}$src_path${gl_bai} -> ${gl_lv}$dest_path${gl_bai}"
                
                if [[ -e "$dest_path" ]]; then
                    if [[ -d "$dest_path" ]]; then
                        local dest_count=$(find "$dest_path" -type f 2>/dev/null | wc -l)
                        echo -e "${gl_bai}目标目录包含 ${gl_huang}$dest_count${gl_bai} 个文件"
                    else
                        local dest_size=$(du -h "$dest_path" 2>/dev/null | cut -f1)
                        echo -e "${gl_bai}目标文件大小: ${gl_huang}$dest_size${gl_bai}"
                    fi
                fi
            else
                log_error "复制失败"
                exit_animation    # 即将退出动画
            fi
            ;;
        [Nn]|"")
            log_warn "已取消操作"
            exit_animation    # 即将退出动画
            ;;
        *) handle_y_n ;;        # 无效的输入,请输入(y或N)。
    esac
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
    return 0
}

search_here() {
    local keyword
    local non_interactive=false

    [[ $# -gt 0 ]] && {
        keyword="$*"
        non_interactive=true
    }

    while true; do
        if [[ "$non_interactive" == false ]]; then

            check_directory_empty "." "当前目录递归内容搜索" "true" || return

            clear
            echo -e ""
            echo -e "${gl_zi}>>> 当前目录递归内容搜索${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "当前目录: ${gl_huang}$(pwd)${gl_bai}"
            echo -e ""
            ls --color=auto -x
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            read -r -e -p "$(echo -e "${gl_bai}请输入要搜索的关键词 (${gl_huang}0${gl_bai}返回): ")" keyword
            [[ "$keyword" == "0" ]] && { cancel_return "上一级选单"; break; }    # break 或 continue 或 return ,视上下文而定
            [[ -z "$keyword" ]] && { cancel_empty "重新输入"; continue; }      # break 或 continue 或 return ,视上下文而定
        fi

        local here
        here="$(pwd)"
        local found=0

        log_info "正在递归扫描 ${gl_huang}${here}${gl_bai} ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
        while IFS= read -r -d '' file; do
            while IFS=: read -r -r line_num content; do
                echo
                echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                log_ok "${file}"
                log_ok "${gl_zi}${line_num}${gl_lv}"
                log_ok "${gl_hui}${content}${gl_bai}"
                echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                ((found++))
            done < <(grep -in --color=always "$keyword" "$file" 2>/dev/null)
        done < <(find "$here" -type f -print0)

        if [[ $found -eq 0 ]]; then
            echo
            log_warn "未在任何文件内找到匹配内容。"
        fi

        [[ "$non_interactive" == true ]] && break

        break_end
    done
}

manual_file_search_and_process() {
    local search_path="${1:-.}"
    check_directory_empty "." "文件搜索并处理" "true" || return

    clear

    if [ -z "$(ls -A 2>/dev/null)" ]; then
        echo -e "${gl_huang}>>> 当前目录文件列表:${gl_bai}(${gl_lv}$(pwd)${gl_bai})"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_huang}当前目录为空${gl_bai}"
    else
        list_dir_colorful 0 4
    fi

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e ""
    echo -e "${gl_zi}>>> 文件搜索并处理${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    echo -e "${gl_huang}文件搜索支持以下模式:${gl_bai}"
    echo -e "${gl_bai}1. 精确文件名: ${gl_lv}example.txt${gl_bai}"
    echo -e "${gl_bai}2. 通配符搜索: ${gl_lv}*.txt${gl_bai}${gl_lv}test-*.jpg${gl_bai}"
    echo -e "${gl_bai}3. 部分匹配: ${gl_lv}*test*${gl_bai}${gl_lv}*.log*${gl_bai}"
    echo -e "${gl_bai}4. 模糊搜索: ${gl_lv}example${gl_bai} (包含此关键词的所有文件)"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    read -r -e -p "$(echo -e "${gl_bai}请输入要搜索的文件名、模式或关键词 (${gl_huang}0${gl_bai}返回): ")" pattern

    case "$pattern" in
    0) cancel_return; return 1 ;;
    esac

    if [[ -z "$pattern" ]]; then
        log_error "搜索模式不能为空!"
        return 1
    fi

    echo -e ""
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}正在搜索模式 ${gl_huang}${pattern}${gl_bai} 的文件${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    local files=()

    if [[ "$pattern" =~ [\*\?\[\]] ]]; then
        while IFS= read -r -d $'\0' file; do
            files+=("$file")
        done < <(find "$search_path" -name "$pattern" -type f -print0 2>/dev/null)
    else
        echo -e "${gl_bai}使用模糊搜索模式: 搜索包含 \"${gl_huang}${pattern}${gl_bai}\" 的文件${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"

        while IFS= read -r -d $'\0' file; do
            files+=("$file")
        done < <(find "$search_path" -type f -iname "*${pattern}*" -print0 2>/dev/null)

        if [[ ${#files[@]} -eq 0 ]]; then
            echo -e "${gl_bai}尝试深度模糊搜索${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
            while IFS= read -r -d $'\0' file; do
                files+=("$file")
            done < <(find "$search_path" -type f -exec grep -l "$pattern" {} \; -print0 2>/dev/null)
        fi
    fi

    if [[ ${#files[@]} -eq 0 ]]; then
        log_warn "未找到任何匹配 ${gl_bufan}${pattern}${gl_bai} 的文件!"

        echo -e "${gl_bai}${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_huang}搜索建议:${gl_bai}"
        echo -e "${gl_bai}1. 尝试不同的关键词或模式"
        echo -e "${gl_bai}2. 使用通配符: ${gl_lv}*${pattern}*${gl_bai}${gl_lv}${pattern}*${gl_bai}"
        echo -e "${gl_bai}3. 尝试搜索当前目录: ${gl_lv}.${gl_bai}"
        echo -e "${gl_bai}4. 使用更广泛的搜索路径"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

        break_end
        return 1
    fi

    mapfile -t sorted_files < <(printf '%s\n' "${files[@]}" | sort)
    files=("${sorted_files[@]}")

    while true; do
        clear
        echo -e "${gl_huang}>>> 找到 ${gl_lv}${#files[@]} ${gl_huang}个匹配 ${gl_bufan}${pattern}${gl_huang} 的文件:${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

        for i in "${!files[@]}"; do
            local abs_path=$(readlink -f "${files[$i]}" 2>/dev/null || realpath "${files[$i]}" 2>/dev/null || echo "${files[$i]}")
            local file_size=$(du -h "${files[$i]}" 2>/dev/null | cut -f1)
            local file_date=$(date -r "${files[$i]}" "+%Y-%m-%d %H:%M" 2>/dev/null)

            if [[ ${#abs_path} -gt 60 ]]; then
                local part1="${abs_path:0:30}"
                local part2="${abs_path: -30}"
                printf "${gl_huang}%3d.${gl_bai} ${gl_lv}%s${gl_bai}${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}${gl_lv}%s${gl_bai} ${gl_huang}%8s${gl_bai} ${gl_zi}%s${gl_bai}\n" \
                    $((i + 1)) \
                    "$part1" \
                    "$part2" \
                    "${file_size:-N/A}" \
                    "${file_date:-N/A}"
            else
                printf "${gl_huang}%3d.${gl_bai} ${gl_lv}%-60s${gl_bai} ${gl_huang}%8s${gl_bai} ${gl_zi}%s${gl_bai}\n" \
                    $((i + 1)) \
                    "$abs_path" \
                    "${file_size:-N/A}" \
                    "${file_date:-N/A}"
            fi
        done
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

        echo -e ""
        echo -e "${gl_zi}>>> 处理搜索到的文件${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}7.  ${gl_bai}预览文件内容        ${gl_bufan}8.  ${gl_bai}查看文件信息"
        echo -e "${gl_bufan}9.  ${gl_bai}批量重命名文件      ${gl_bufan}10. ${gl_bai}文件权限批量修改"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_bufan}11. ${gl_bai}切到文件所在目录    ${gl_bufan}12. ${gl_bai}下载文件到本地"
        echo -e "${gl_bufan}13. ${gl_bai}文件管理工具        ${gl_bufan}14. ${gl_bai}图片格式转换工具"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_huang}0.  ${gl_bai}返回上一级选单      ${gl_hong}00. ${gl_bai}退出脚本"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

        read -r -e -p "$(echo -e "${gl_bai}请输入你的选择: ")" choice

        case $choice in
        1) # 复制独立文件
            echo -e ""
            echo -e "${gl_zi}>>> 复制独立文件${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            read -r -e -p "$(echo -e "${gl_bai}请输入要复制的文件编号 (多个用空格分隔) (${gl_huang}0${gl_bai}返回): ")" indices

            case "$indices" in
            0) cancel_return "处理搜索到的文件"; continue ;;
            esac

            read -r -e -p "$(echo -e "${gl_bai}请输入目标目录: ")" target_dir

            if [[ ! -d "$target_dir" ]]; then
                read -r -e -p "$(echo -e "${gl_bai}目标目录不存在,是否创建? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" create_dir
                case "$create_dir" in
                [Yy])
                    mkdir -p "$target_dir" && log_ok "目录已创建: ${gl_bufan}$target_dir${gl_bai}" || {
                        log_error "创建目录失败!"
                        break_end
                        return 1
                    }
                    ;;
                [Nn])
                    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                    echo -e "${gl_huang}已取消安装${gl_bufan}mobufan${gl_huang}脚本${gl_bai}"
                    echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
                    read -r -n 1 -s -r -p ""
                    continue # 返回菜单
                    ;;
                0) cancel_return "处理搜索到的文件"; continue ;;
                *) handle_y_n; continue ;;
                esac
            fi

            local copy_count=0
            for idx in $indices; do
                local file_idx=$((idx - 1))
                if [[ $file_idx -ge 0 && $file_idx -lt ${#files[@]} ]]; then
                    if cp "${files[$file_idx]}" "$target_dir/" 2>/dev/null; then
                        log_ok "已复制: ${gl_bufan}$(basename "${files[$file_idx]}")${gl_bai} -> ${gl_lv}$target_dir/${gl_bai}"
                        ((copy_count++))
                        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                        echo -e "${gl_lv}复制完成${gl_bai}"
                        echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
                        read -r -n 1 -s -r -p ""
                        continue # 完成后返回菜单
                    else
                        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                        echo -e "${gl_hong}复制复制失败: ${gl_bufan}${files[$file_idx]}${gl_bai}"
                        echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
                        read -r -n 1 -s -r -p ""
                        continue # 完成后返回菜单
                    fi
                fi
            done
            ;;
        2) # 复制全部文件
            echo -e ""
            echo -e "${gl_zi}>>> 复制全部文件${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            read -r -e -p "$(echo -e "${gl_bai}请输入目标目录 (${gl_huang}0${gl_bai}返回): ")" target_dir

            case "$target_dir" in
            0) cancel_return "处理搜索到的文件"; continue ;;
            esac

            if [[ ! -d "$target_dir" ]]; then
                read -r -e -p "$(echo -e "${gl_bai}目标目录不存在,是否创建? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" create_dir
                case "$create_dir" in
                [Yy])
                    mkdir -p "$target_dir" && log_ok "目录已创建: ${gl_bufan}$target_dir${gl_bai}" || {
                        log_error "创建目录失败!"
                        break_end
                        return 1
                    }
                    ;;
                [Nn])
                    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                    echo -e "${gl_huang}已取消安装${gl_bufan}mobufan${gl_huang}脚本${gl_bai}"
                    echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
                    read -r -n 1 -s -r -p ""
                    continue # 返回菜单
                    ;;
                *)
                    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                    handle_y_n        # 无效的输入,请输入(y或N)。
                    continue # 返回菜单
                    ;;
                esac
            fi

            local copy_count=0
            for file in "${files[@]}"; do
                if cp "$file" "$target_dir/" 2>/dev/null; then
                    log_info "已复制: ${gl_bufan}$(basename "$file")${gl_bai}"
                    ((copy_count++))
                else
                    log_error "复制失败: ${gl_bufan}$file${gl_bai}"
                fi
            done
            if [[ $copy_count -gt 0 ]]; then
                log_ok "成功复制 ${copy_count}/${#files[@]} 个文件到: ${gl_bufan}$target_dir/${gl_bai}"
            fi
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_lv}复制完成${gl_bai}"
            echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
            read -r -n 1 -s -r -p ""
            continue # 完成后返回菜单
            ;;
        3) # 移动独立文件
            echo -e ""
            echo -e "${gl_zi}>>> 移动独立文件${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            read -r -e -p "$(echo -e "${gl_bai}请输入要移动的文件编号 (多个用空格分隔) (${gl_huang}0${gl_bai}返回): ")" indices

            case "$indices" in
            0) cancel_return "处理搜索到的文件"; continue ;;
            esac

            read -r -e -p "$(echo -e "${gl_bai}请输入目标目录: ")" target_dir

            if [[ ! -d "$target_dir" ]]; then
                read -r -e -p "$(echo -e "${gl_bai}目标目录不存在,是否创建? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" create_dir
                case "$create_dir" in
                [Yy])
                    mkdir -p "$target_dir" && log_ok "目录已创建: ${gl_bufan}$target_dir${gl_bai}" || {
                        log_error "创建目录失败!"
                        break_end
                        return 1
                    }
                    ;;
                [Nn])
                    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                    echo -e "${gl_huang}已取消安装${gl_bufan}mobufan${gl_huang}脚本${gl_bai}"
                    echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
                    read -r -n 1 -s -r -p ""
                    continue # 返回菜单
                    ;;
                *)
                    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                    handle_y_n        # 无效的输入,请输入(y或N)。
                    continue # 返回菜单
                    ;;
                esac
            fi

            local sorted_indices=($(echo "$indices" | tr ' ' '\n' | sort -unr))
            local move_count=0

            for idx in "${sorted_indices[@]}"; do
                local file_idx=$((idx - 1))
                if [[ $file_idx -ge 0 && $file_idx -lt ${#files[@]} ]]; then
                    if mv "${files[$file_idx]}" "$target_dir/" 2>/dev/null; then
                        log_ok "已移动: ${gl_bufan}$(basename "${files[$file_idx]}")${gl_bai} -> ${gl_lv}$target_dir/${gl_bai}"
                        unset 'files[file_idx]' # 从数组中移除
                        ((move_count++))
                    else
                        log_error "移动失败: ${gl_bufan}${files[$file_idx]}${gl_bai}"
                    fi
                fi
            done

            files=("${files[@]}")

            if [[ $move_count -gt 0 ]]; then
                log_ok "成功移动 ${move_count} 个文件"
            fi

            if [[ ${#files[@]} -eq 0 ]]; then
                log_warn "所有文件已移动,返回上级菜单"
                exit_animation    # 即将退出动画
                break
            fi

            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_lv}移动完成${gl_bai}"
            echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
            read -r -n 1 -s -r -p ""
            continue # 完成后返回菜单(已刷新)
            ;;
        4) # 移动全部文件
            echo -e ""
            echo -e "${gl_zi}>>> 移动全部文件${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            read -r -e -p "$(echo -e "${gl_bai}请输入目标目录 (${gl_huang}0${gl_bai}返回): ")" target_dir

            case "$target_dir" in
            0) cancel_return "处理搜索到的文件"; continue ;;
            esac

            if [[ ! -d "$target_dir" ]]; then
                read -r -e -p "$(echo -e "${gl_bai}目标目录不存在,是否创建? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" create_dir
                case "$create_dir" in
                [Yy])
                    mkdir -p "$target_dir" && log_ok "目录已创建: ${gl_bufan}$target_dir${gl_bai}" || {
                        log_error "创建目录失败!"
                        break_end
                        return 1
                    }
                    ;;
                [Nn])
                    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                    echo -e "${gl_huang}已取消安装${gl_bufan}mobufan${gl_huang}脚本${gl_bai}"
                    echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
                    read -r -n 1 -s -r -p ""
                    continue # 返回菜单
                    ;;
                *)
                    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                    handle_y_n        # 无效的输入,请输入(y或N)。
                    continue # 返回菜单
                    ;;
                esac
            fi

            local move_count=0
            for file in "${files[@]}"; do
                if mv "$file" "$target_dir/" 2>/dev/null; then
                    log_info "已移动: ${gl_bufan}$(basename "$file")${gl_bai}"
                    ((move_count++))
                else
                    log_error "移动失败: ${gl_bufan}$file${gl_bai}"
                fi
            done
            if [[ $move_count -gt 0 ]]; then
                log_ok "成功移动 ${move_count}/${#files[@]} 个文件到: ${gl_bufan}$target_dir/${gl_bai}"
            fi

            files=()
            break_end
            break # 退出菜单(无文件剩余)
            ;;
        5) # 删除独立文件
            echo -e ""
            echo -e "${gl_zi}>>> 删除独立文件${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            read -r -e -p "$(echo -e "${gl_bai}请输入要删除的文件编号 (多个用空格分隔) (${gl_huang}0${gl_bai}返回): ")" indices

            case "$indices" in
            0) cancel_return "处理搜索到的文件"; continue ;;
            esac

            echo -e "${gl_bai}${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_hong}警告:${gl_bai}以下文件将被删除:"
            for idx in $indices; do
                local file_idx=$((idx - 1))
                if [[ $file_idx -ge 0 && $file_idx -lt ${#files[@]} ]]; then
                    echo -e "  ${gl_bufan}${files[$file_idx]}${gl_bai}"
                fi
            done
            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

            case "$confirm" in
            [Yy])
                local sorted_indices=($(echo "$indices" | tr ' ' '\n' | sort -unr))
                local delete_count=0

                for idx in "${sorted_indices[@]}"; do
                    local file_idx=$((idx - 1))
                    if [[ $file_idx -ge 0 && $file_idx -lt ${#files[@]} ]]; then
                        if rm -f "${files[$file_idx]}" 2>/dev/null; then
                            log_ok "已删除: ${gl_bufan}$(basename "${files[$file_idx]}")${gl_bai}"
                            unset 'files[file_idx]' # 从数组中移除已删除的文件
                            ((delete_count++))
                        else
                            log_error "删除失败: ${gl_bufan}${files[$file_idx]}${gl_bai}"
                        fi
                    fi
                done

                files=("${files[@]}")

                if [[ $delete_count -gt 0 ]]; then
                    log_ok "成功删除 ${delete_count} 个文件"
                    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                    echo -e "${gl_lv}删除完成${gl_bai}"
                    echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
                    read -r -n 1 -s -r -p ""
                    continue # 完成后返回菜单(已刷新)
                fi

                if [[ ${#files[@]} -eq 0 ]]; then
                    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                    echo -e "${gl_lv}删除完成${gl_bai}"
                    echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
                    read -r -n 1 -s -r -p ""
                    continue # 完成后返回菜单(已刷新)
                fi
                ;;
            [Nn])
                echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                echo -e "${gl_huang}已取消安装${gl_bufan}mobufan${gl_huang}脚本${gl_bai}"
                echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
                read -r -n 1 -s -r -p ""
                continue # 返回菜单
                ;;
            *)
                echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                handle_y_n        # 无效的输入,请输入(y或N)。
                continue # 返回菜单
                ;;
            esac
            ;;
        6) # 删除全部文件
            echo -e ""
            echo -e "${gl_zi}>>> 删除全部文件${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_hong}警告:${gl_bai}将删除所有 ${#files[@]} 个匹配的文件!"
            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

            case "$confirm" in
            [Yy])
                local delete_count=0
                for file in "${files[@]}"; do
                    if rm -f "$file" 2>/dev/null; then
                        log_info "已删除: ${gl_bufan}$(basename "$file")${gl_bai}"
                        ((delete_count++))
                    else
                        log_error "删除失败: ${gl_bufan}$file${gl_bai}"
                    fi
                done
                if [[ $delete_count -gt 0 ]]; then
                    log_ok "成功删除 ${delete_count}/${#files[@]} 个文件"
                fi
                echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                echo -e "${gl_lv}删除完成${gl_bai}"
                echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
                read -r -n 1 -s -r -p ""

                files=()
                continue # 返回菜单
                ;;
            [Nn])
                echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                echo -e "${gl_huang}已取消安装${gl_bufan}mobufan${gl_huang}脚本${gl_bai}"
                exit_animation    # 即将退出动画
                continue # 返回菜单
                ;;
            *)
                echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                handle_y_n        # 无效的输入,请输入(y或N)。
                continue # 返回菜单
                ;;
            esac
            ;;
        7) # 预览文件内容
            echo -e ""
            echo -e "${gl_zi}>>> 预览文件内容${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            read -r -e -p "$(echo -e "${gl_bai}请输入要预览的文件编号 (${gl_huang}0${gl_bai}返回): ")" idx

            case "$idx" in
            0) cancel_return "处理搜索到的文件"; continue ;;
            esac

            local file_idx=$((idx - 1))
            if [[ $file_idx -ge 0 && $file_idx -lt ${#files[@]} ]]; then
                local preview_file="${files[$file_idx]}"
                echo -e "${gl_bai}${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                echo -e "${gl_bai}预览文件: ${gl_huang}$preview_file${gl_bai}"
                echo -e "${gl_bai}文件大小: ${gl_lv}$(du -h "$preview_file" 2>/dev/null | cut -f1)${gl_bai}"
                echo -e "${gl_bai}最后修改: ${gl_zi}$(date -r "$preview_file" "+%Y-%m-%d %H:%M:%S" 2>/dev/null)${gl_bai}"
                echo -e "${gl_bai}${gl_bufan}————————————————————————————————————————————————${gl_bai}"

                local file_type=$(file -b "$preview_file" 2>/dev/null)
                echo -e "${gl_bai}文件类型: ${gl_bufan}${file_type:-未知}${gl_bai}"

                if [[ -f "$preview_file" ]]; then
                    echo -e "${gl_bai}${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                    echo -e "${gl_bai}文件前 20 行内容:${gl_bai}"
                    echo -e "${gl_bai}${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                    head -n 20 "$preview_file" 2>/dev/null
                else
                    log_error "无法读取文件: ${gl_bufan}$preview_file${gl_bai}"
                fi
                echo -e "${gl_bai}${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
                read -r -n 1 -s -r -p ""
            else
                log_error "无效的文件编号!"
                echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
                read -r -n 1 -s -r -p ""
            fi
            continue # 预览完成后返回菜单
            ;;
        8) # 查看文件信息
            echo -e ""
            echo -e "${gl_zi}>>> 查看文件信息${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            read -r -e -p "$(echo -e "${gl_bai}请输入要查看的文件编号 (${gl_huang}0${gl_bai}返回): ")" idx

            case "$idx" in
            0) cancel_return "处理搜索到的文件"; continue ;;
            esac

            local file_idx=$((idx - 1))
            if [[ $file_idx -ge 0 && $file_idx -lt ${#files[@]} ]]; then
                local info_file="${files[$file_idx]}"
                echo -e "${gl_bai}${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                echo -e ""
                echo -e "${gl_huang}文件详细信息:${gl_bai}"
                echo -e "${gl_bai}${gl_bufan}————————————————————————————————————————————————${gl_bai}"

                if command -v stat &>/dev/null; then
                    echo -e "${gl_bai}文件名: ${gl_lv}$(basename "$info_file")${gl_bai}"
                    echo -e "${gl_bai}完整路径: ${gl_bufan}$info_file${gl_bai}"
                    echo -e "${gl_bai}文件大小: ${gl_zi}$(du -h "$info_file" 2>/dev/null | cut -f1)${gl_bai}"
                    echo -e "${gl_bai}文件类型: ${gl_bufan}$(file -b "$info_file" 2>/dev/null)${gl_bai}"
                    echo -e "${gl_bai}权限: ${gl_lv}$(stat -c "%A" "$info_file" 2>/dev/null)${gl_bai}"
                    echo -e "${gl_bai}所有者: ${gl_huang}$(stat -c "%U:%G" "$info_file" 2>/dev/null)${gl_bai}"
                    echo -e "${gl_bai}创建时间: ${gl_zi}$(stat -c "%w" "$info_file" 2>/dev/null)${gl_bai}"
                    echo -e "${gl_bai}修改时间: ${gl_zi}$(stat -c "%y" "$info_file" 2>/dev/null)${gl_bai}"
                    echo -e "${gl_bai}访问时间: ${gl_zi}$(stat -c "%x" "$info_file" 2>/dev/null)${gl_bai}"
                else
                    ls -la "$info_file" 2>/dev/null
                fi

                if [[ "$info_file" =~ \.(txt|sh|bash|zsh|py|js|html|css|json|xml|md|yml|yaml)$ ]]; then
                    echo -e "${gl_bai}文件编码: ${gl_lv}$(file -bi "$info_file" 2>/dev/null | grep -oP 'charset=\K[^;]+' || echo "未知")${gl_bai}"
                fi

                echo -e "${gl_bai}${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
                read -r -n 1 -s -r -p ""
            else
                echo -e "${gl_bai}${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                handle_y_n        # 无效的输入,请输入(y或N)。
                continue # 返回菜单
            fi
            continue # 查看完成后返回菜单
            ;;
        9) # 批量重命名文件
            echo -e ""
            echo -e "${gl_zi}>>> 批量重命名文件${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_bai}重命名模式:${gl_bai}"
            echo -e "${gl_bufan}1. ${gl_bai}添加前缀${gl_bai}        ${gl_bufan}2. ${gl_bai}添加后缀${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_bufan}3. ${gl_bai}替换字符串${gl_bai}      ${gl_bufan}4. ${gl_bai}序号重命名${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            read -r -e -p "$(echo -e "${gl_bai}请选择重命名模式 (${gl_huang}0${gl_bai}返回): ")" rename_mode

            case "$rename_mode" in
            0) cancel_return "处理搜索到的文件"; continue ;;
            1) # 添加前缀
                read -r -e -p "$(echo -e "${gl_bai}请输入要添加的前缀: ")" prefix
                local rename_count=0
                for file in "${files[@]}"; do
                    local filename=$(basename "$file")
                    local dir=$(dirname "$file")
                    local newname="${dir}/${prefix}${filename}"
                    if mv "$file" "$newname" 2>/dev/null; then
                        log_ok "已重命名: ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}${prefix}${filename}${gl_bai}"
                        ((rename_count++))
                    fi
                done
                ;;
            2) # 添加后缀
                read -r -e -p "$(echo -e "${gl_bai}请输入要添加的后缀 (不含扩展名): ")" suffix
                local rename_count=0
                for file in "${files[@]}"; do
                    local filename=$(basename "$file")
                    local dir=$(dirname "$file")
                    local ext="${filename##*.}"
                    local name="${filename%.*}"
                    local newname="${dir}/${name}${suffix}.${ext}"
                    if [[ "$filename" == "$ext" ]]; then
                        newname="${dir}/${filename}${suffix}"
                    fi
                    if mv "$file" "$newname" 2>/dev/null; then
                        log_ok "已重命名: ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}$(basename "$newname")${gl_bai}"
                        ((rename_count++))
                    fi
                done
                ;;
            3) # 替换字符串
                read -r -e -p "$(echo -e "${gl_bai}请输入要替换的字符串: ")" old_str
                read -r -e -p "$(echo -e "${gl_bai}请输入替换为的字符串: ")" new_str
                local rename_count=0
                for file in "${files[@]}"; do
                    local filename=$(basename "$file")
                    local dir=$(dirname "$file")
                    local newname="${dir}/${filename//$old_str/$new_str}"
                    if [[ "$filename" != "$(basename "$newname")" ]]; then
                        if mv "$file" "$newname" 2>/dev/null; then
                            log_ok "已重命名: ${gl_bufan}${filename}${gl_bai} -> ${gl_lv}$(basename "$newname")${gl_bai}"
                            ((rename_count++))
                        fi
                    fi
                done
                ;;
            4) # 序号重命名
                read -r -e -p "$(echo -e "${gl_bai}请输入文件名模板 (如: file-###.txt, ### 将被替换为序号): ")" template
                local rename_count=0
                local idx=1
                for file in "${files[@]}"; do
                    local dir=$(dirname "$file")
                    local ext="${file##*.}"
                    local newname="${dir}/${template//###/$(printf "%03d" $idx)}"
                    if [[ "$template" != *"###"* ]]; then
                        newname="${dir}/${template}_${idx}.${ext}"
                    fi
                    if mv "$file" "$newname" 2>/dev/null; then
                        log_ok "已重命名: ${gl_bufan}$(basename "$file")${gl_bai} -> ${gl_lv}$(basename "$newname")${gl_bai}"
                        ((rename_count++))
                    fi
                    ((idx++))
                done
                ;;
            *) handle_invalid_input ;;
            esac

            if [[ $rename_count -gt 0 ]]; then
                log_ok "成功重命名 ${rename_count} 个文件"
                files=()
                while IFS= read -r -d $'\0' file; do
                    files+=("$file")
                done < <(find "$search_path" -name "$pattern" -type f -print0 2>/dev/null)
                mapfile -t sorted_files < <(printf '%s\n' "${files[@]}" | sort)
                files=("${sorted_files[@]}")
            fi
            echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
            read -r -n 1 -s -r -p ""
            continue
            ;;
        10) # 文件权限批量修改
            echo -e ""
            echo -e "${gl_zi}>>> 批量修改文件权限${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_bai}权限设置:${gl_bai}"
            echo -e "${gl_bai}1. ${gl_lv}755${gl_bai} (rwxr-xr-x) - 可执行文件"
            echo -e "${gl_bai}2. ${gl_lv}644${gl_bai} (rw-r--r--) - 普通文件"
            echo -e "${gl_bai}3. ${gl_lv}600${gl_bai} (rw-------) - 敏感文件"
            echo -e "${gl_bai}4. ${gl_lv}777${gl_bai} (rwxrwxrwx) - 完全开放"
            echo -e "${gl_bai}5. ${gl_lv}自定义${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            read -r -e -p "$(echo -e "${gl_bai}请选择权限模式 (${gl_huang}0${gl_bai}返回): ")" perm_mode

            local chmod_val=""
            case "$perm_mode" in
            0) cancel_return "处理搜索到的文件"; continue ;;
            1) chmod_val="755" ;;
            2) chmod_val="644" ;;
            3) chmod_val="600" ;;
            4) chmod_val="777" ;;
            5)
                read -r -e -p "$(echo -e "${gl_bai}请输入权限值 (如: 755, 644): ")" chmod_val
                ;;
            *)
                handle_invalid_input
                continue
                ;;
            esac

            if [[ -n "$chmod_val" ]]; then
                local chmod_count=0
                for file in "${files[@]}"; do
                    if chmod "$chmod_val" "$file" 2>/dev/null; then
                        log_info "已修改权限: ${gl_bufan}$(basename "$file")${gl_bai} -> ${gl_lv}$chmod_val${gl_bai}"
                        ((chmod_count++))
                    else
                        log_error "修改失败: ${gl_bufan}$file${gl_bai}"
                    fi
                done
                if [[ $chmod_count -gt 0 ]]; then
                    log_ok "成功修改 ${chmod_count}/${#files[@]} 个文件的权限"
                fi
            fi
            echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
            read -r -n 1 -s -r -p ""
            continue
            ;;
        11) # 切换到文件目录
            echo -e ""
            echo -e "${gl_zi}>>> 切换到文件所在目录${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            read -r -e -p "$(echo -e "${gl_bai}请输入要切换目录的文件编号 (${gl_huang}0${gl_bai}返回): ")" idx

            case "$idx" in
            0) cancel_return "处理搜索到的文件"; continue ;;
            esac

            local file_idx=$((idx - 1))
            if [[ $file_idx -ge 0 && $file_idx -lt ${#files[@]} ]]; then
                local target_file="${files[$file_idx]}"
                local abs_path=$(readlink -f "$target_file" 2>/dev/null || realpath "$target_file" 2>/dev/null || echo "$target_file")
                local target_dir=$(dirname "$abs_path")

                if cd "$target_dir" 2>/dev/null; then
                    log_ok "已切换到目录: ${gl_lv}$target_dir${gl_bai}"
                else
                    log_error "切换目录失败: ${gl_huang}$target_dir${gl_bai}"
                fi
            else
                log_error "无效的文件编号!"
            fi
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            exit_animation    # 即将退出动画
            list_dir_colorful 0 4
            continue # 返回菜单
            ;;
        12) rz_download_files_to_local; continue ;;             # 下载文件到本地
        13) linux_file "." "处理搜索到的文件" "处理搜索到的文件";; # 文件管理工具
        14) image_converter_main "处理搜索到的文件" ;;            # 图片格式转换工具
        0) cancel_return; break ;;                              # 返回上一级选单
        00 | 000 | 0000) exit_script ;;
        *) handle_invalid_input ;;
        esac
    done

    return 0
}

duwatch() {
    local dir
    if [[ -n $1 ]]; then
        dir=$1
    else
        echo -e ""
        echo -e "${gl_zi}>>> 实时监控目录大小${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        read -r -e -p "输入要监控的目录 (默认当前目录): " dir
        dir=${dir:-.}
    fi

    if [[ ! -d $dir ]]; then
        echo -e "${gl_hong}目录不存在: ${gl_huang}$dir${gl_bai}" >&2
        exit_animation    # 即将退出动画
        return 1
    fi

    echo -e ""
    echo -e "${gl_bai}开始监控: ${gl_lv}$(realpath "$dir")  ${gl_bai}${gl_huang}Ctrl-C 停止${gl_bai})"
    if du -sb "$dir" 2>&1 | grep -q "权限不够"; then
        echo -e "${gl_huang}提示: 部分文件因权限无法访问,统计结果可能小于实际占用${gl_bai}"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    while :; do
        local size_mb
        size_mb=$(du -sb "$dir" 2>/dev/null | awk '{print $1/1024/1024}')

        if (($(echo "$size_mb > 1024" | bc -l 2>/dev/null || echo "0"))); then
            printf '%(%F %T)T\t%.2f GB\n' -1 "$(echo "$size_mb/1024" | bc -l)"
        else
            printf '%(%F %T)T\t%.3f MB\n' -1 "$size_mb"
        fi
        sleep_fractional 2
    done
}

remove_duplicate_files() {
    local search_path="."
    local method="md5"
    local total_files_count=0
    local duplicate_files_count=0
    local total_duplicate_size=0
    declare -gA duplicate_groups

    while true; do

        check_directory_empty "." "文件去重工具" "true" || return

        clear
        if [ -z "$(ls -A "$search_path" 2>/dev/null)" ]; then
            echo -e "${gl_huang}当前目录为空${gl_bai}"
        else
            cd ${search_path} && list_dir_colorful 0 4
        fi
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e ""
        echo -e "${gl_zi}>>> 文件去重工具${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}切换去重方法 (当前: ${gl_lv}${method}${gl_bai})"
        echo -e "${gl_bufan}5.  ${gl_bai}设置搜索路径      ${gl_bufan}6.  ${gl_bai}查看扫描统计"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_huang}0.  ${gl_bai}返回上一级选单    ${gl_hong}00. ${gl_bai}退出脚本"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

        read -r -e -p "$(echo -e "${gl_bai}请输入你的选择: ")" choice

        case $choice in
        1) scan_duplicate_files ;;
        2) interactive_remove_duplicates ;;
        3) auto_remove_duplicates ;;
        4) switch_duplicate_method ;;
        5) set_duplicate_search_path ;;
        6) show_scan_statistics ;;
        0) cancel_return; break ;;                        # 返回上一级选单
        00 | 000 | 0000) exit_script ;;
        *) handle_invalid_input ;;
        esac
    done
}

scan_duplicate_files() {
    echo -e "${gl_bai}正在扫描重复文件${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo -e ""

    if [[ "$method" == "md5" ]] && ! command -v md5sum &>/dev/null; then
        log_error "md5sum 命令未找到,请安装 coreutils 或使用其他去重方法"
        exit_animation    # 即将退出动画
        return 1
    elif [[ "$method" == "sha1" ]] && ! command -v sha1sum &>/dev/null; then
        log_error "sha1sum 命令未找到,请安装 coreutils 或使用其他去重方法"
        exit_animation    # 即将退出动画
        return 1
    fi

    get_duplicate_groups

    echo -e ""
    echo -e "${gl_zi}>>> 重复文件扫描结果${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    if [[ ${#duplicate_groups[@]} -eq 0 ]]; then
        log_ok "未发现重复文件!"
        echo -e "${gl_bai}扫描路径: ${gl_lv}${search_path}${gl_bai}"
        echo -e "${gl_bai}去重方法: ${gl_huang}${method}${gl_bai}"
        echo -e "${gl_bai}文件总数: ${gl_lv}${total_files_count}${gl_bai}"
    else
        echo -e "${gl_bai}扫描路径: ${gl_lv}${search_path}${gl_bai}"
        echo -e "${gl_bai}去重方法: ${gl_huang}${method}${gl_bai}"
        echo -e "${gl_bai}文件总数: ${gl_lv}${total_files_count}${gl_bai}"
        echo -e "${gl_bai}重复文件: ${gl_hong}${duplicate_files_count}${gl_bai}"

        if [[ $duplicate_files_count -gt 0 ]]; then
            local duplicate_size_mb=$(echo "scale=2; $total_duplicate_size / 1024 / 1024" | bc 2>/dev/null || echo "0")
            echo -e "${gl_bai}浪费空间: ${gl_hong}${duplicate_size_mb} MB${gl_bai}"
        fi

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

        local group_count=0
        for checksum in "${!duplicate_groups[@]}"; do
            IFS='|' read -ra files <<<"${duplicate_groups[$checksum]}"
            if [[ ${#files[@]} -gt 1 ]]; then
                group_count=$((group_count + 1))
                echo -e "${gl_huang}${group_count} 组重复文件 (${#files[@]} 个):${gl_bai}"

                for i in "${!files[@]}"; do
                    local file="${files[$i]}"
                    if [[ -f "$file" ]]; then
                        local file_size=$(stat -c%s "$file" 2>/dev/null || echo 0)
                        local size_human=$(numfmt --to=iec --suffix=B "$file_size" 2>/dev/null || echo "${file_size}B")
                        local mtime=$(stat -c "%y" "$file" 2>/dev/null | cut -d'.' -f1 2>/dev/null || echo "未知")

                        if [[ $i -eq 0 ]]; then
                            echo -e "  ${gl_lv}${file}${gl_bai} (${size_human}, ${mtime}) - ${gl_lv}[保留建议]${gl_bai}"
                        else
                            echo -e "  ${gl_hui}${i}. ${file}${gl_bai} (${size_human}, ${mtime})"
                        fi
                    else
                        echo -e "  ${gl_hong}× ${file}${gl_bai} (文件不存在或无法访问)"
                    fi
                done
                echo -e ""
            fi
        done

        if [[ $group_count -eq 0 ]]; then
            log_ok "未发现重复文件!"
        else
            echo -e "${gl_bai}共发现 ${gl_hong}${group_count}${gl_bai} 组重复文件"
        fi
    fi

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
    read -r -n 1 -s -r -p ""
}

image_converter_main() {
    local menu_name="${1:-上一级选单}"
    while true; do
        install ffmpeg

        check_directory_empty "." "图片格式转换工具" "true" || return

        clear
        echo -e "${gl_zi}>>> 图片格式转换工具${gl_bai}(${gl_lv}$(pwd)${gl_bai})"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

        local image_files=()
        local image_sizes=()
        image_converter_find_images image_files image_sizes

        if [[ ${#image_files[@]} -eq 0 ]]; then
            echo -e "${gl_huang}当前目录没有找到图片文件${gl_bai}"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -ne "${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.5
            return
        else
            image_converter_show_list image_files image_sizes
        fi

        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_bufan}1.  ${gl_bai}指定转${gl_bufan}JPG${gl_bai}格式       ${gl_bufan}2.  ${gl_bai}全部转${gl_bufan}JPG${gl_bai}格式"
        echo -e "${gl_bufan}3.  ${gl_bai}指定转${gl_bufan}PNG${gl_bai}格式       ${gl_bufan}4.  ${gl_bai}全部转${gl_bufan}PNG${gl_bai}格式"
        echo -e "${gl_bufan}5.  ${gl_bai}指定转${gl_bufan}WEBP${gl_bai}格式      ${gl_bufan}6.  ${gl_bai}全部转${gl_bufan}WEBP${gl_bai}格式"
        echo -e "${gl_bufan}7.  ${gl_bai}指定转${gl_bufan}BMP${gl_bai}格式       ${gl_bufan}8.  ${gl_bai}全部转${gl_bufan}BMP${gl_bai}格式"
        echo -e "${gl_bufan}9.  ${gl_bai}指定转${gl_bufan}JPEG${gl_bai}格式      ${gl_bufan}10. ${gl_bai}全部转${gl_bufan}JPEG${gl_bai}格式"
        echo -e "${gl_bufan}11. ${gl_bai}指定转${gl_bufan}GIF${gl_bai}格式       ${gl_bufan}12. ${gl_bai}全部转${gl_bufan}GIF${gl_bai}格式"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_bufan}13. ${gl_bai}质量压缩图片        ${gl_bufan}14. ${gl_bai}批量调整尺寸${gl_bai}"
        echo -e "${gl_bufan}15. ${gl_bai}批量重命名          ${gl_bufan}16. ${gl_bai}批量删除图片${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_huang}0.  ${gl_bai}返回上一级选单      ${gl_hong}00. ${gl_bai}退出脚本"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

        read -r -e -p "$(echo -e "${gl_bai}请输入你的选择: ")" choice

        case $choice in
        1)  image_converter_convert_selected "jpg" image_files ;;   # 指定转JPG格式
        2)  image_converter_batch_all "jpg" image_files ;;          # 全部转JPG格式
        3)  image_converter_convert_selected "png" image_files ;;   # 指定转PNG格式
        4)  image_converter_batch_all "png" image_files ;;          # 全部转PNG格式
        5)  image_converter_convert_selected "webp" image_files ;;  # 指定转WEBP格式
        6)  image_converter_batch_all "webp" image_files ;;         # 全部转WEBP格式
        7)  image_converter_convert_selected "bmp" image_files ;;   # 指定转BMP格式
        8)  image_converter_batch_all "bmp" image_files ;;          # 全部转BMP格式
        9)  image_converter_convert_selected "jpeg" image_files ;;  # 指定转JPEG格式
        10) image_converter_batch_all "jpeg" image_files ;;         # 全部转JPEG格式
        11) image_converter_convert_selected "gif" image_files ;;   # 指定转GIF格式
        12) image_converter_batch_all "gif" image_files ;;          # 全部转GIF格式
        13) image_converter_compress_quality image_files ;;         # 质量压缩图片
        14) image_converter_resize_batch image_files ;;             # 批量调整尺寸
        15) image_converter_batch_rename image_files ;;             # 批量重命名
        16) image_converter_batch_delete image_files ;;             # 批量删除图片
        0) cancel_return "$menu_name"; break ;;                     # 返回到上一级菜单
        00 | 000 | 0000) exit_script ;;                             # 感谢使用,再见!
        *) handle_invalid_input ;;                                  # 无效的输入,请重新输入!
        esac
    done
}

image_converter_find_images() {
    local -n files_ref=$1
    local -n sizes_ref=$2

    files_ref=()
    sizes_ref=()

    local exts=("jpg" "jpeg" "png" "bmp" "gif" "tiff" "tif" "webp" "heic" "JPG" "JPEG" "PNG" "BMP" "GIF" "TIFF" "TIF" "WEBP" "HEIC")

    for ext in "${exts[@]}"; do
        for file in *."$ext"; do
            if [[ -f "$file" ]] && [[ "$file" != *\* ]]; then
                files_ref+=("$file")
            fi
        done
    done

    if [[ ${#files_ref[@]} -gt 0 ]]; then
        IFS=$'\n' files_ref=($(printf '%s\n' "${files_ref[@]}" | sort))
        unset IFS
    fi

    for file in "${files_ref[@]}"; do
        if [[ -f "$file" ]]; then
            local size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null || echo "0")
            if [[ $size -ge 1048576 ]]; then
                local size_display=$(echo "scale=1; $size/1048576" | bc 2>/dev/null || echo "0")M
            elif [[ $size -ge 1024 ]]; then
                local size_display=$(echo "scale=1; $size/1024" | bc 2>/dev/null || echo "0")K
            else
                local size_display="${size}B"
            fi
        else
            local size_display="未知"
        fi
        sizes_ref+=("$size_display")
    done
}

image_converter_show_list() {
    local -n files_ref=$1
    local -n sizes_ref=$2

    for i in "${!files_ref[@]}"; do
        local file="${files_ref[i]}"
        local resolution="未知"

        if command -v identify &>/dev/null; then
            resolution=$(identify -format "%wx%h" "$file" 2>/dev/null || echo "未知")
        elif command -v ffprobe &>/dev/null; then
            resolution=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 "$file" 2>/dev/null | tr ',' 'x' || echo "未知")
        elif [[ "$file" =~ \.(jpg|jpeg|png|gif|bmp|tiff|tif|webp)$ ]]; then
            resolution=$(file "$file" 2>/dev/null | grep -oE "[0-9]+ x [0-9]+" | head -1 | tr ' ' 'x' || echo "未知")
        fi

        if [[ "$resolution" == "" ]] || [[ "$resolution" == "x" ]]; then
            resolution="未知"
        fi

        printf "${gl_huang}%3d${gl_bai}.  ${gl_lv}%-25s${gl_bai}  ${gl_zi}%12s${gl_bai}  ${gl_lan}%8s${gl_bai}\n" \
            $((i + 1)) "${files_ref[i]}" "$resolution" "${sizes_ref[i]}"
    done
}

image_converter_convert_single() {
    local file="${1:-}"
    local format="${2:-}"

    if [[ ! -f "$file" ]]; then
        log_error "文件不存在: $file"
        return 1
    fi

    local filename=$(basename "$file")
    local name="${filename%.*}"

    local new_name="${name}.${format}"
    local count=1
    while [[ -f "$new_name" ]]; do
        new_name="${name}_${count}.${format}"
        count=$((count + 1))
    done

    log_info "开始转换: ${filename}${new_name}"

    if ffmpeg -i "$file" "$new_name" 2>/dev/null; then
        local input_size=$(du -h "$file" 2>/dev/null | cut -f1)
        local output_size=$(du -h "$new_name" 2>/dev/null | cut -f1)
        log_ok "转换成功"
        log_info "原文件: ${filename} (${input_size:-未知})"
        log_info "新文件: ${new_name} (${output_size:-未知})"
        return 0
    else
        log_error "转换失败: ${filename}"
        return 1
    fi
}

image_converter_batch_all() {
    local format="${1:-}"
    local -n files_ref=$2

    if [[ ${#files_ref[@]} -eq 0 ]]; then
        log_error "没有图片可转换"
        return
    fi

    echo ""
    log_info "开始批量转换全部图片为 ${format} 格式${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo ""

    local success=0
    local total=${#files_ref[@]}

    for i in "${!files_ref[@]}"; do
        local file="${files_ref[i]}"
        local progress=$(((i + 1) * 100 / total))

        printf "\r${gl_bai}处理中: [${gl_lv}%3d%%${gl_bai}] ${gl_huang}%d/${total}${gl_bai} - ${gl_lan}%s${gl_bai}" \
            "$progress" "$((i + 1))" "$file"

        if image_converter_convert_single "$file" "$format" >/dev/null 2>&1; then
            success=$((success + 1))
        fi
    done

    echo -e "\n\n${gl_bufan}————————————————————————${gl_bai}"
    log_ok "批量转换完成"
    log_info "成功: ${gl_lv}${success}${gl_bai} 个文件"
    if [[ $((total - success)) -gt 0 ]]; then
        log_warn "失败: ${gl_huang}$((total - success))${gl_bai} 个文件"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    break_end
}

image_converter_convert_selected() {
    local format="${1:-}"
    local -n files_ref=$2

    if [[ ${#files_ref[@]} -eq 0 ]]; then
        log_error "没有图片可选"
        return
    fi

    echo ""
    echo -e "${gl_bai}请选择要转换的图片序号${gl_bai}"
    echo -e "${gl_huang}支持: 单个序号, 多个用空格分隔, 范围用'-'连接${gl_bai}"
    echo -e "${gl_huang}示例: 1 3 5 或 2-5 或 1,3,7${gl_bai}"
    echo ""

    read -r -e -p "$(echo -e "${gl_bai}请输入你的选择 (${gl_huang}0${gl_bai}返回): ")" selection

    [[ -z "$selection" ]] && { cancel_empty "上一级选单"; return 1; }       # break 或 continue 或 return ,视上下文而定
    [[ "$selection" == "0" ]] && { cancel_return "上一级选单"; return; }    # break 或 continue 或 return ,视上下文而定

    local selected_files=()

    selection=$(echo "$selection" | tr ',' ' ')

    if [[ "$selection" =~ ^[0-9]+-[0-9]+$ ]]; then
        local start=${selection%-*}
        local end=${selection#*-}
        for ((i = start; i <= end; i++)); do
            if [[ $i -ge 1 ]] && [[ $i -le ${#files_ref[@]} ]]; then
                selected_files+=("${files_ref[$((i - 1))]}")
            fi
        done
    else
        for num in $selection; do
            if [[ $num =~ ^[0-9]+$ ]]; then
                if [[ $num -ge 1 ]] && [[ $num -le ${#files_ref[@]} ]]; then
                    selected_files+=("${files_ref[$((num - 1))]}")
                else
                    log_warn "序号 ${num} 无效"
                fi
            fi
        done
    fi

    if [[ ${#selected_files[@]} -eq 0 ]]; then
        log_error "没有选择有效的图片"
        return
    fi

    echo ""
    echo -e "${gl_bai}选择的图片:${gl_bai}"
    for file in "${selected_files[@]}"; do
        echo -e "  ${gl_lv}${gl_bai} $file"
    done
    echo ""

    read -r -e -p "$(echo -e "${gl_bai}确认转换这 ${#selected_files[@]} 个文件为 ${format} 格式? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
    if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
        log_info "操作取消"
        return
    fi

    echo ""
    log_info "开始转换${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo ""

    local success=0
    local total=${#selected_files[@]}

    for i in "${!selected_files[@]}"; do
        local file="${selected_files[i]}"
        echo -e "${gl_huang}[$((i + 1))/$total]${gl_bai} 处理: $file"

        if image_converter_convert_single "$file" "$format"; then
            success=$((success + 1))
        fi
        echo ""
    done

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    log_ok "转换完成"
    log_info "成功: ${gl_lv}${success}${gl_bai} 个文件"
    if [[ $((total - success)) -gt 0 ]]; then
        log_warn "失败: ${gl_huang}$((total - success))${gl_bai} 个文件"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    break_end
}

image_converter_compress_quality() {
    local -n files_ref=$1

    if [[ ${#files_ref[@]} -eq 0 ]]; then
        log_error "没有图片可压缩"
        return
    fi

    echo ""
    echo -e "${gl_bai}请选择要压缩的图片序号${gl_bai}"
    echo -e "${gl_huang}支持: 单个序号, 多个用空格分隔, 范围用'-'连接${gl_bai}"
    echo -e "${gl_huang}示例: 1 3 5 或 2-5 或 1,3,7${gl_bai}"
    echo ""

    read -r -e -p "$(echo -e "${gl_bai}请输入你的选择 (${gl_huang}0${gl_bai}返回): ")" selection

    [[ -z "$selection" ]] && { cancel_empty "上一级选单"; return 1; }
    [[ "$selection" == "0" ]] && { cancel_return "上一级选单"; return 1; }

    local selected_files=()
    selection=$(echo "$selection" | tr ',' ' ')

    if [[ "$selection" =~ ^[0-9]+-[0-9]+$ ]]; then
        local start=${selection%-*}
        local end=${selection#*-}
        for ((i = start; i <= end; i++)); do
            if [[ $i -ge 1 ]] && [[ $i -le ${#files_ref[@]} ]]; then
                selected_files+=("${files_ref[$((i - 1))]}")
            fi
        done
    else
        for num in $selection; do
            if [[ $num =~ ^[0-9]+$ ]]; then
                if [[ $num -ge 1 ]] && [[ $num -le ${#files_ref[@]} ]]; then
                    selected_files+=("${files_ref[$((num - 1))]}")
                else
                    log_warn "序号 ${num} 无效"
                fi
            fi
        done
    fi

    if [[ ${#selected_files[@]} -eq 0 ]]; then
        log_error "没有选择有效的图片"
        return
    fi

    echo ""
    echo -e "${gl_bai}输入质量参数 (1-100, 默认85)${gl_bai}"
    echo -e "${gl_huang}数值越高质量越好, 文件越大${gl_bai}"

    read -r -e -p "$(echo -e "${gl_bai}请输入质量 (${gl_huang}1-100${gl_bai}): ")" quality
    quality=${quality:-85}

    if ! [[ "$quality" =~ ^[0-9]+$ ]] || [ "$quality" -lt 1 ] || [ "$quality" -gt 100 ]; then
        log_error "质量参数无效, 使用默认值85"
        quality=85
    fi

    echo ""
    echo -e "${gl_bai}选择的图片:${gl_bai}"
    for file in "${selected_files[@]}"; do
        echo -e "  ${gl_lv}${gl_bai} $file"
    done
    echo ""

    read -r -e -p "$(echo -e "${gl_bai}确认压缩这 ${#selected_files[@]} 个文件? 质量: ${quality} (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
    if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
        log_info "操作取消"
        return
    fi

    local success=0
    local total=${#selected_files[@]}

    for i in "${!selected_files[@]}"; do
        local file="${selected_files[i]}"
        local filename=$(basename "$file")
        local extension="${filename##*.}"
        local name="${filename%.*}"
        local new_name="${name}_compressed.${extension}"
        local count=1

        while [[ -f "$new_name" ]]; do
            new_name="${name}_compressed_${count}.${extension}"
            count=$((count + 1))
        done

        echo -e "${gl_huang}[$((i + 1))/$total]${gl_bai} 压缩: $file"

        if ffmpeg -i "$file" -q:v "$quality" "$new_name" 2>/dev/null; then
            log_ok "压缩成功: $new_name"
            success=$((success + 1))
        else
            log_error "压缩失败: $file"
        fi
    done

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    log_ok "压缩完成"
    log_info "成功: ${gl_lv}${success}${gl_bai} 个文件"
    if [[ $((total - success)) -gt 0 ]]; then
        log_warn "失败: ${gl_huang}$((total - success))${gl_bai} 个文件"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    break_end
}

image_converter_resize_batch() {
    local -n files_ref=$1

    if [[ ${#files_ref[@]} -eq 0 ]]; then
        log_error "没有图片可调整"
        return
    fi

    echo ""
    echo -e "${gl_bai}请选择调整模式${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 ""

    read -r -e -p "$(echo -e "${gl_bai}请输入模式 (${gl_huang}1-4${gl_bai}): ")" mode

    case $mode in
    1)
        read -r -e -p "$(echo -e "${gl_bai}请输入目标宽度: ")" width
        if ! [[ "$width" =~ ^[0-9]+$ ]]; then
            log_error "无效的宽度"
            return
        fi
        resize_cmd="-vf scale=${width}:-1"
        ;;
    2)
        read -r -e -p "$(echo -e "${gl_bai}请输入目标高度: ")" height
        if ! [[ "$height" =~ ^[0-9]+$ ]]; then
            log_error "无效的高度"
            return
        fi
        resize_cmd="-vf scale=-1:${height}"
        ;;
    3)
        read -r -e -p "$(echo -e "${gl_bai}请输入缩放百分比 (如50表示50%): ")" percent
        if ! [[ "$percent" =~ ^[0-9]+$ ]]; then
            log_error "无效的百分比"
            return
        fi
        local scale_percent=$(echo "scale=2; $percent/100" | bc)
        resize_cmd="-vf scale=iw*${scale_percent}:ih*${scale_percent}"
        ;;
    4)
        read -r -e -p "$(echo -e "${gl_bai}请输入目标宽度: ")" width
        read -r -e -p "$(echo -e "${gl_bai}请输入目标高度: ")" height
        if ! [[ "$width" =~ ^[0-9]+$ ]] || ! [[ "$height" =~ ^[0-9]+$ ]]; then
            log_error "无效的尺寸"
            return
        fi
        resize_cmd="-vf scale=${width}:${height}"
        ;;
    *)
        log_error "无效的模式"
        return
        ;;
    esac

    echo ""
    echo -e "${gl_bai}请选择要调整的图片${gl_bai}"
    echo -e "${gl_bai}输入 ${gl_lv}all${gl_bai} 批量处理所有图片"
    echo -e "${gl_bai}或输入序号 (用空格分隔, 如 1 3 5)${gl_bai}"

    read -r -e -p "$(echo -e "${gl_bai}请输入你的选择 (${gl_huang}0${gl_bai}返回): ")" selection

    [[ -z "$selection" ]] && { cancel_empty "上一级选单"; return 1; }        # break 或 continue 或 return ,视上下文而定
    [[ "$selection" == "0" ]] && { cancel_return "上一级选单"; return; }     # break 或 continue 或 return ,视上下文而定

    local selected_files=()

    if [[ "$selection" == "all" ]]; then
        selected_files=("${files_ref[@]}")
    else
        selection=$(echo "$selection" | tr ',' ' ')

        if [[ "$selection" =~ ^[0-9]+-[0-9]+$ ]]; then
            local start=${selection%-*}
            local end=${selection#*-}
            for ((i = start; i <= end; i++)); do
                if [[ $i -ge 1 ]] && [[ $i -le ${#files_ref[@]} ]]; then
                    selected_files+=("${files_ref[$((i - 1))]}")
                fi
            done
        else
            for num in $selection; do
                if [[ $num =~ ^[0-9]+$ ]]; then
                    if [[ $num -ge 1 ]] && [[ $num -le ${#files_ref[@]} ]]; then
                        selected_files+=("${files_ref[$((num - 1))]}")
                    else
                        log_warn "序号 ${num} 无效"
                    fi
                fi
            done
        fi
    fi

    if [[ ${#selected_files[@]} -eq 0 ]]; then
        log_error "没有选择有效的图片"
        return
    fi

    echo ""
    echo -e "${gl_bai}选择的图片:${gl_bai}"
    for file in "${selected_files[@]}"; do
        echo -e "  ${gl_lv}${gl_bai} $file"
    done
    echo ""

    read -r -e -p "$(echo -e "${gl_bai}确认调整这 ${#selected_files[@]} 个文件的尺寸? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
    if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
        log_info "操作取消"
        return
    fi

    local success=0
    local total=${#selected_files[@]}

    for i in "${!selected_files[@]}"; do
        local file="${selected_files[i]}"
        local filename=$(basename "$file")
        local extension="${filename##*.}"
        local name="${filename%.*}"
        local new_name="${name}_resized.${extension}"
        local count=1

        while [[ -f "$new_name" ]]; do
            new_name="${name}_resized_${count}.${extension}"
            count=$((count + 1))
        done

        echo -e "${gl_huang}[$((i + 1))/$total]${gl_bai} 调整: $file"

        if ffmpeg -i "$file" $resize_cmd "$new_name" 2>/dev/null; then
            log_ok "调整成功: $new_name"
            success=$((success + 1))
        else
            log_error "调整失败: $file"
        fi
    done

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    log_ok "尺寸调整完成"
    log_info "成功: ${gl_lv}${success}${gl_bai} 个文件"
    if [[ $((total - success)) -gt 0 ]]; then
        log_warn "失败: ${gl_huang}$((total - success))${gl_bai} 个文件"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    break_end
}

image_converter_batch_rename() {
    local -n files_ref=$1

    if [[ ${#files_ref[@]} -eq 0 ]]; then
        log_error "没有图片可重命名"
        return
    fi

    echo ""
    echo -e "${gl_bai}批量重命名图片${gl_bai}"
    echo -e "${gl_huang}请输入新的文件名前缀${gl_bai}"
    echo -e "${gl_huang}示例: 输入 ${gl_bai}photo${gl_huang}, 会生成 ${gl_bai}photo_001.jpg, photo_002.png${gl_huang}${gl_bai}"

    read -r -e -p "$(echo -e "${gl_bai}请输入前缀 (${gl_huang}0${gl_bai}返回): ")" prefix

    [[ -z "$prefix" ]] && { cancel_empty "上一级选单"; return 1; }       # break 或 continue 或 return ,视上下文而定
    [[ "$prefix" == "0" ]] && { cancel_return "上一级选单"; return 1; }    # break 或 continue 或 return ,视上下文而定

    echo ""
    echo -e "${gl_bai}是否保持原扩展名?${gl_bai}"
    echo -e "${gl_huang}保持: 文件扩展名不变"
    echo -e "统一: 所有图片使用相同的扩展名${gl_bai}"
    echo ""
    echo -e "${gl_bufan}1.  ${gl_bai}保持原扩展名"
    echo -e "${gl_bufan}2.  ${gl_bai}统一为JPG格式"
    echo -e "${gl_bufan}3.  ${gl_bai}统一为PNG格式"
    echo -e "${gl_bufan}4.  ${gl_bai}统一为WEBP格式"
    echo ""

    read -r -e -p "$(echo -e "${gl_bai}请选择 (${gl_huang}1-4${gl_bai}): ")" ext_choice

    case $ext_choice in
    1) keep_original=true ;;
    2) target_ext="jpg" ;;
    3) target_ext="png" ;;
    4) target_ext="webp" ;;
    *)
        log_error "无效的选择"
        return
        ;;
    esac

    echo ""
    echo -e "${gl_bai}请选择要重命名的图片${gl_bai}"
    echo -e "${gl_bai}输入 ${gl_lv}all${gl_bai} 批量处理所有图片"
    echo -e "${gl_bai}或输入序号 (用空格分隔)${gl_bai}"

    read -r -e -p "$(echo -e "${gl_bai}请输入选择 (${gl_huang}0${gl_bai}返回): ")" selection

    [[ -z "$selection" ]] && { cancel_empty "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
    [[ "$selection" == "0" ]] && { cancel_return "上一级选单"; return 1; } # break 或 continue 或 return ,视上下文而定

    local selected_files=()

    if [[ "$selection" == "all" ]]; then
        selected_files=("${files_ref[@]}")
    else
        selection=$(echo "$selection" | tr ',' ' ')

        if [[ "$selection" =~ ^[0-9]+-[0-9]+$ ]]; then
            local start=${selection%-*}
            local end=${selection#*-}
            for ((i = start; i <= end; i++)); do
                if [[ $i -ge 1 ]] && [[ $i -le ${#files_ref[@]} ]]; then
                    selected_files+=("${files_ref[$((i - 1))]}")
                fi
            done
        else
            for num in $selection; do
                if [[ $num =~ ^[0-9]+$ ]]; then
                    if [[ $num -ge 1 ]] && [[ $num -le ${#files_ref[@]} ]]; then
                        selected_files+=("${files_ref[$((num - 1))]}")
                    else
                        log_warn "序号 ${num} 无效"
                    fi
                fi
            done
        fi
    fi

    if [[ ${#selected_files[@]} -eq 0 ]]; then
        log_error "没有选择有效的图片"
        return
    fi

    echo ""
    echo -e "${gl_bai}选择的图片:${gl_bai}"
    for file in "${selected_files[@]}"; do
        echo -e "  ${gl_lv}${gl_bai} $file"
    done
    echo ""

    read -r -e -p "$(echo -e "${gl_bai}确认重命名这 ${#selected_files[@]} 个文件? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" confirm
    if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
        log_info "操作取消"
        return
    fi

    local success=0
    local total=${#selected_files[@]}

    for i in "${!selected_files[@]}"; do
        local file="${selected_files[i]}"
        local filename=$(basename "$file")

        if [[ "$keep_original" == "true" ]]; then
            local extension="${filename##*.}"
        else
            local extension="$target_ext"
        fi

        local index=$(printf "%03d" $((i + 1)))
        local new_name="${prefix}_${index}.${extension}"
        local count=1

        while [[ -f "$new_name" ]]; do
            new_name="${prefix}_${index}_${count}.${extension}"
            count=$((count + 1))
        done

        echo -e "${gl_huang}[$((i + 1))/$total]${gl_bai} 重命名: $file$new_name"

        if mv "$file" "$new_name" 2>/dev/null; then
            files_ref[$i]="$new_name"
            log_ok "重命名成功"
            success=$((success + 1))
        else
            log_error "重命名失败: $file"
        fi
    done

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    log_ok "重命名完成"
    log_info "成功: ${gl_lv}${success}${gl_bai} 个文件"
    if [[ $((total - success)) -gt 0 ]]; then
        log_warn "失败: ${gl_huang}$((total - success))${gl_bai} 个文件"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    break_end
}

image_converter_batch_delete() {
    local -n files_ref=$1

    if [[ ${#files_ref[@]} -eq 0 ]]; then
        log_error "没有图片可删除"
        return
    fi

    echo ""
    echo -e "${gl_bai}批量删除图片${gl_bai}"
    echo -e "${gl_hong}警告: 此操作不可恢复!${gl_bai}"
    echo ""
    echo -e "${gl_bai}请选择要删除的图片${gl_bai}"
    echo -e "${gl_bai}输入 ${gl_lv}all${gl_bai} 删除所有图片"
    echo -e "${gl_bai}或输入序号 (用空格分隔)${gl_bai}"

    read -r -e -p "$(echo -e "${gl_bai}请输入选择 (${gl_huang}0${gl_bai}返回): ")" selection

    [[ -z "$selection" ]] && { cancel_empty "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
    [[ "$selection" == "0" ]] && { cancel_return "上一级选单"; return 1; } # break 或 continue 或 return ,视上下文而定

    local selected_files=()

    if [[ "$selection" == "all" ]]; then
        selected_files=("${files_ref[@]}")
    else
        selection=$(echo "$selection" | tr ',' ' ')

        if [[ "$selection" =~ ^[0-9]+-[0-9]+$ ]]; then
            local start=${selection%-*}
            local end=${selection#*-}
            for ((i = start; i <= end; i++)); do
                if [[ $i -ge 1 ]] && [[ $i -le ${#files_ref[@]} ]]; then
                    selected_files+=("${files_ref[$((i - 1))]}")
                fi
            done
        else
            for num in $selection; do
                if [[ $num =~ ^[0-9]+$ ]]; then
                    if [[ $num -ge 1 ]] && [[ $num -le ${#files_ref[@]} ]]; then
                        selected_files+=("${files_ref[$((num - 1))]}")
                    else
                        log_warn "序号 ${num} 无效"
                    fi
                fi
            done
        fi
    fi

    if [[ ${#selected_files[@]} -eq 0 ]]; then
        log_error "没有选择有效的图片"
        return
    fi

    echo ""
    echo -e "${gl_bai}将要删除的图片:${gl_bai}"
    for file in "${selected_files[@]}"; do
        echo -e "  ${gl_hong}${gl_bai} $file"
    done
    echo ""

    read -r -e -p "$(echo -e "${gl_hong}确认删除这 ${#selected_files[@]} 个文件? 此操作不可恢复! (${gl_hong}Y${gl_bai}/${gl_lv}n${gl_bai}): ")" confirm
    if [[ ! "$confirm" =~ ^[Yy]$ ]] && [[ -z "$confirm" ]]; then
        log_info "操作取消"
        return
    fi

    echo ""
    read -r -e -p "$(echo -e "${gl_hong}最后确认! 输入${gl_lv}confirm${gl_hong}以继续删除: ")" final_confirm
    if [[ "$final_confirm" != "confirm" ]]; then
        log_info "操作取消"
        return
    fi

    local success=0
    local total=${#selected_files[@]}

    for i in "${!selected_files[@]}"; do
        local file="${selected_files[i]}"
        echo -e "${gl_huang}[$((i + 1))/$total]${gl_bai} 删除: $file"

        if rm -f "$file" 2>/dev/null; then
            log_ok "删除成功"
            success=$((success + 1))
        else
            log_error "删除失败: $file"
        fi
    done

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    log_ok "删除完成"
    log_info "成功: ${gl_lv}${success}${gl_bai} 个文件"
    if [[ $((total - success)) -gt 0 ]]; then
        log_warn "失败: ${gl_huang}$((total - success))${gl_bai} 个文件"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    break_end
}

transfer_file_to_remote() {
    local file_to_transfer=""
    local remote_ip=""
    local remote_user=""
    local remote_password=""
    local remote_port=""
    local user_input=""
    
    clear
    
    if ! list_files "." 0 4; then
        echo -e "${gl_huang}当前目录没有可传输的文件${gl_bai}"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    if [[ ${#LIST_FILES_ARRAY[@]} -eq 0 ]] || [[ "$LIST_FILES_COUNT" -eq 0 ]]; then
        echo -e "${gl_huang}当前目录没有可传输的文件${gl_bai}"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    echo ""
    echo -e "${gl_zi}>>> 传送文件至远端服务器${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -r -e -p "$(echo -e "${gl_bai}输入序号选择文件,或直接输入文件路径 (${gl_huang}0${gl_bai}返回): ")" user_input
    
    [[ -z "$user_input" ]] && { cancel_empty "上一级选单"; return 1; }                       # break 或 continue 或 return ,视上下文而定
    [[ "$user_input" == "0" ]] && { cancel_return "文件管理器"; return 1; }      # break 或 continue 或 return ,视上下文而定
    
    if [[ "$user_input" =~ ^[0-9]+$ ]]; then
        local idx=$((user_input - 1))
        if ((idx >= 0 && idx < LIST_FILES_COUNT)); then
            file_to_transfer="${LIST_FILES_ARRAY[$idx]}"
            log_ok "已选择 [$user_input]: $file_to_transfer"
        else
            log_error "无效的序号: $user_input (有效范围: 1-$LIST_FILES_COUNT)"
            exit_animation    # 即将退出动画
            return 1
        fi
    else
        file_to_transfer="$user_input"
        if [[ ! -f "$file_to_transfer" ]]; then
            log_error "文件不存在: $file_to_transfer"
            exit_animation    # 即将退出动画
            return 1
        fi
        log_ok "已指定文件: $file_to_transfer"
    fi
    
    if [[ ! -f "$file_to_transfer" ]]; then
        log_error "无法访问文件: $file_to_transfer"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    echo ""
    echo -e "${gl_bai}源文件: ${gl_huang}$file_to_transfer${gl_bai}"
    local file_size=$(du -h "$file_to_transfer" 2>/dev/null | cut -f1)
    echo -e "${gl_bai}文件大小: ${gl_huang}$file_size${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    read -r -e -p "$(echo -e "${gl_bai}请输入远端服务器IP: ")" remote_ip
    [ "$remote_ip" = "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
    if [[ -z "$remote_ip" ]]; then
        log_error "远端服务器IP不能为空"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    read -r -e -p "$(echo -e "${gl_bai}请输入远端服务器用户名 (${gl_lv}默认root${gl_bai}): ")" remote_user
    [ "$remote_user" = "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
    remote_user=${remote_user:-root}
    
    read -r -e -p "$(echo -e "${gl_bai}请输入远端服务器密码: ")" -s remote_password
    [ "$remote_password" = "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
    echo ""
    if [[ -z "$remote_password" ]]; then
        log_error "密码不能为空"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    read -r -e -p "$(echo -e "${gl_bai}请输入登录端口 (${gl_lv}默认22${gl_bai}): ")" remote_port
    [ "$remote_port" = "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
    remote_port=${remote_port:-22}
    
    echo ""
    echo -e "${gl_huang}传送信息确认:${gl_bai}"
    echo -e "${gl_bai}文件: ${gl_huang}$file_to_transfer${gl_bai}"
    echo -e "${gl_bai}目标: ${gl_huang}$remote_user@$remote_ip:$remote_port${gl_bai}"
    echo -e "${gl_bai}目标目录: ${gl_huang}/home/${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
    [ "$confirm" = "0" ] && { cancel_return "上一级选单"; return 1; }      # break 或 continue 或 return ,视上下文而定
    
    if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
        log_warn "已取消操作"
        exit_animation    # 即将退出动画
        return 1
    fi
    
    log_info "清理SSH已知主机记录${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
    ssh-keygen -f "/root/.ssh/known_hosts" -R "$remote_ip" 2>/dev/null
    
    echo -e "${gl_bai}正在传送文件${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    if scp -P "$remote_port" -o StrictHostKeyChecking=no -o ConnectTimeout=30 "$file_to_transfer" "$remote_user@$remote_ip:/home/" <<< "$remote_password"; then
        echo ""
        log_ok "文件传送成功"
        echo -e "${gl_bai}文件已传送至: ${gl_lv}$remote_user@$remote_ip:/home/$file_to_transfer${gl_bai}"
    else
        echo ""
        log_error "文件传送失败"
        echo -e "${gl_huang}可能原因:${gl_bai}"
        echo -e "  1. 网络连接失败"
        echo -e "  2. IP地址或端口错误"
        echo -e "  3. 用户名或密码错误"
        echo -e "  4. 远端服务器SSH服务未启动"
        echo -e "  5. 防火墙阻止连接"
        return 1
    fi
    
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
    return 0
}

select_and_display_file_info() {
    local target_dir="${1:-.}"
    local show_hidden="${2:-0}"
    local custom_cols="${3:-2}"
    
    LIST_CURRENT_DIR="$target_dir"
    
    clear
    if ! list_files "$target_dir" "$show_hidden" "$custom_cols"; then
        echo -e "${gl_lv}即将退出${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
        sleep_fractional 0.8
        return
    fi
    
    echo -e ""
    echo -e "${gl_huang}请选择操作:${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "  ${gl_lv}[1-${LIST_FILES_COUNT}]${gl_bai} 查看对应文件/目录详情"
    echo -e "  ${gl_lv}[r]${gl_bai} 刷新当前目录"
    echo -e "  ${gl_huang}[0]${gl_bai} 返回上一级选单"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    
    read -r -e -p "$(echo -e "${gl_bai}请输入你的选择(${gl_huang}0${gl_bai}返回): ")" user_choice
    
    case "$user_choice" in
        [1-9]|[1-9][0-9]|[1-9][0-9][0-9])
            if (( user_choice >= 1 && user_choice <= LIST_FILES_COUNT )); then
                local index=$((user_choice - 1))
                local selected_file="${LIST_FILES_ARRAY[$index]}"
                local full_path="${LIST_CURRENT_DIR%/}/${selected_file}"
                
                clear
                
                local absolute_path=$(realpath "$full_path" 2>/dev/null || echo "$full_path")
                echo -e ""
                echo -e "${gl_huang}📁 文件/目录信息${gl_bai}"
                echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                echo -e ""
                echo -e "${gl_lv}🔍 选中文件: ${gl_bai}${selected_file}"
                echo -e "${gl_lv}📁 相对路径: ${gl_bai}${full_path}"
                echo -e "${gl_lv}📍 绝对路径: ${gl_bai}${absolute_path}"
                echo -e ""
                echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                
                display_file_info "$full_path" "true"
                
                echo -e ""
                echo -e "${gl_huang}操作菜单:${gl_bai}"
                echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                echo -e "  ${gl_lv}[enter]${gl_bai} 返回文件列表"
                echo -e "  ${gl_lv}[e]${gl_bai} 编辑文件"
                echo -e "  ${gl_huang}[0]${gl_bai} 返回上一级选单"
                echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
                
                read -rp "$(echo -e ${gl_bai}"请输入你的选择: "${gl_bai})" file_action
                
                case "$file_action" in
                    "")
                        clear
                        select_and_display_file_info "$target_dir" "$show_hidden" "$custom_cols"
                        ;;
                    "e"|"E")
                        if [ -f "$full_path" ]; then
                            if command -v nano &>/dev/null; then
                                nano "$full_path"
                            elif command -v vi &>/dev/null; then
                                vi "$full_path"
                            elif command -v vim &>/dev/null; then
                                vim "$full_path"
                            else
                                echo -e "${gl_hong}未找到可用的编辑器${gl_bai}"
                                read -n1 -rp "$(echo -e ${gl_huang}"按任意键继续{gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"${gl_bai})"
                            fi
                        else
                            echo -e "${gl_hong}不能编辑目录${gl_bai}"
                            read -n1 -rp "$(echo -e ${gl_huang}"按任意键继续{gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"${gl_bai})"
                        fi
                        clear
                        select_and_display_file_info "$target_dir" "$show_hidden" "$custom_cols"
                        ;;
                    0)  create_directory || return 0 ;;
                    *)
                        clear
                        select_and_display_file_info "$target_dir" "$show_hidden" "$custom_cols"
                        ;;
                esac
            else
                echo -e "${gl_hong}无效的选择序号${gl_bai}"
                read -n1 -rp "$(echo -e ${gl_huang}"按任意键继续{gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"${gl_bai})"
                clear
                select_and_display_file_info "$target_dir" "$show_hidden" "$custom_cols"
            fi
            ;;
        "r"|"R")
            clear
            select_and_display_file_info "$target_dir" "$show_hidden" "$custom_cols"
            ;;
        0) cancel_return; return 0 ;;    # 返回到上一级菜单
        *)
            echo -e "${gl_hong}无效的选择${gl_bai}"
            read -n1 -rp "$(echo -e ${gl_huang}"按任意键继续{gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"${gl_bai})"
            clear
            select_and_display_file_info "$target_dir" "$show_hidden" "$custom_cols"
            ;;
    esac
    
    return 0
}

show_directory_tree() {
    install tree
    check_directory_empty "." "生成目录树" "true" || return
    clear
    echo -e "${gl_zi}当前 ${gl_huang}$(pwd)${gl_zi} 目录树${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    tree . 2>/dev/null || find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

interactive_delete() {
    echo -e ""

    if [[ -z "$TRASH_CMD" ]]; then
        install_trash
    fi

    while true; do
        check_directory_empty "." "删除模式" "true" || return

        clear

        if ! list_files "." 0 4; then
            exit_animation    # 即将退出动画
            return 1
        fi

        if [[ ${#LIST_FILES_ARRAY[@]} -eq 0 ]] || [[ "$LIST_FILES_COUNT" -eq 0 ]]; then
            exit_animation    # 即将退出动画
            return 1
        fi
        local list=("${LIST_FILES_ARRAY[@]}")

        echo -e ""
        echo -e "${gl_zi}>>> 删除模式${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        read -r -e -p "$(echo -e "${gl_bai}请输入序号 (多选用空格分隔) (${gl_huang}0 ${gl_bai}返回, ${gl_hong}c${gl_bai} 清空目录): ")" -e raw

        [ -z "$raw" ] && { cancel_empty "上一级选单"; return 1; }        # break 或 continue 或 return ,视上下文而定
        [ "$raw" = "0" ] && { cancel_return "上一级选单"; return 1; }   # break 或 continue 或 return ,视上下文而定

        if [[ $raw == "c" || $raw == "C" ]]; then
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_hong}⚠ 警告:您选择了清空当前目录!${gl_bai}"
            echo -e "${gl_huang}当前目录 ${gl_lv}$(pwd) ${gl_bai}下共有 ${gl_lv}${#list[@]}${gl_bai} 个文件/目录"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

            echo -e "${gl_huang}将要删除以下所有内容:${gl_bai}"
            for item in "${list[@]}"; do
                if [[ -d "$item" ]]; then
                    echo -e "  ${gl_bai}目录: ${gl_zi}$item${gl_bai}"
                else
                    echo -e "  ${gl_bai}文件: ${gl_lv}$item${gl_bai}"
                fi
            done
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

            read -r -e -p "$(echo -e "${gl_bai}确认要清空当前目录吗?(输入 ${gl_hong}yes${gl_bai} 确认): ")" confirm_response

            if [[ $confirm_response == "yes" ]]; then
                local ok=0 fail=0

                for item in "${list[@]}"; do
                    if [[ -n "$TRASH_CMD" ]]; then
                        if delete_file_with_trash "$item"; then
                            ((ok++))
                        else
                            ((fail++))
                        fi
                    else
                        if delete_file_with_trash "$item"; then
                            ((ok++))
                        else
                            ((fail++))
                        fi
                    fi
                done

                if [[ -n "$TRASH_CMD" ]]; then
                    if ((ok > 0)); then
                        echo -e "${gl_lv}✓ 成功移动 ${gl_huang}$ok${gl_bai} 项到回收站${gl_bai}"
                    fi
                    if ((fail > 0)); then
                        echo -e "${gl_hong}$fail 项移动失败${gl_bai}"
                    fi
                else
                    if ((ok > 0)); then
                        echo -e "${gl_lv}✓ 成功删除 ${gl_huang}$ok${gl_bai}${gl_bai}"
                    fi
                    if ((fail > 0)); then
                        echo -e "${gl_hong}$fail 项删除失败${gl_bai}"
                    fi
                fi
            else
                echo -e "${gl_huang}已取消清空目录操作${gl_bai}"
            fi

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

        local to_del=() tok idx
        read -r -a tokens <<<"$raw"

        for tok in "${tokens[@]}"; do
            [[ -z "$tok" ]] && continue

            if [[ $tok =~ ^[0-9]+$ ]] && ((tok >= 1 && tok <= ${#list[@]})); then
                local selected_item="${list[$((tok - 1))]}"
                [[ -e "$selected_item" ]] && to_del+=("$selected_item")
                continue
            fi

            local glob_result=()
            shopt -s nullglob
            glob_result=($tok) # 故意不加双引号,让 bash 展开
            shopt -u nullglob

            if ((${#glob_result[@]})); then
                for item in "${glob_result[@]}"; do
                    [[ "$item" == ./* ]] && item="${item#./}"
                    [[ -e "$item" ]] && to_del+=("$item")
                done
                continue
            fi

            if [[ -e "$tok" ]]; then
                to_del+=("$tok")
            else
                echo -e "${gl_hong}跳过无效输入或文件不存在: $tok${gl_bai}"
            fi
        done
        ((${#to_del[@]} == 0)) && {
            echo -e "${gl_huang}没有有效的文件可删除${gl_bai}"
            exit_animation    # 即将退出动画
            continue
        }

        echo
        echo -e "${gl_huang}>>> 即将删除以下 ${gl_bufan}${#to_del[@]}${gl_bai} ${gl_huang}项:"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        for item in "${to_del[@]}"; do
            echo -e "  ${gl_lv}$item${gl_bai}"
        done

        local confirm_response
        if [[ -n "$TRASH_CMD" ]]; then
            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_response
        else
            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_response
        fi

        [[ $confirm_response =~ ^[Yy]$ ]] || {
            echo -e "${gl_huang}操作已取消${gl_bai}"
            exit_animation    # 即将退出动画
            continue
        }

        local ok=0 fail=0
        for item in "${to_del[@]}"; do
            if [[ -n "$TRASH_CMD" ]]; then
                if delete_file_with_trash "$item"; then
                    ((ok++))
                else
                    ((fail++))
                fi
            else
                if delete_file_with_trash "$item"; then
                    ((ok++))
                else
                    ((fail++))
                fi
            fi
        done

        if [[ -n "$TRASH_CMD" ]]; then
            if ((ok > 0)); then
                echo -e "${gl_lv}✓ 成功移动 ${gl_huang}$ok${gl_bai} 项到回收站${gl_bai}"
            fi
            if ((fail > 0)); then
                echo -e "${gl_hong}$fail 项移动失败${gl_bai}"
            fi
        else
            if ((ok > 0)); then
                echo -e "${gl_lv}✓ 成功删除 ${gl_huang}$ok${gl_bai}${gl_bai}"
            fi
            if ((fail > 0)); then
                echo -e "${gl_hong}$fail 项删除失败${gl_bai}"
            fi
        fi

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

check_rm_redirect_silent() {
    local user_shell=$(basename "$SHELL")
    local config_file=""

    case "$user_shell" in
    bash)
        config_file="$HOME/.bashrc"
        ;;
    zsh)
        config_file="$HOME/.zshrc"
        ;;
    *)
        return
        ;;
    esac

    if grep -q "alias rm=" "$config_file" 2>/dev/null; then
        echo -e "${gl_bufan}rm  重定向: ${gl_lv}已启用${gl_bai}"
    else
        echo -e "${gl_bufan}rm  重定向: ${gl_hui}未启用${gl_bai}"
    fi
}

show_trash_contents_and_stats() {
    if [[ -z "$TRASH_CMD" ]]; then
        echo -e "${gl_huang}回收站未启用${gl_bai}"
        return
    fi

    local trash_json=$(get_trash_list)
    local item_count=0
    local total_files=0
    local total_dirs=0
    local total_size=0

    if command -v jq &>/dev/null; then
        item_count=$(echo "$trash_json" | jq length)
    else
        item_count=$(echo "$trash_json" | grep -o '"index"' | wc -l)
    fi

    if [[ $item_count -eq 0 ]]; then
        echo -e "${gl_huang}回收站为空${gl_bai}"
        return
    fi

    echo -e "${gl_huang}回收站中的文件:${gl_bai}"
    echo

    local files=()
    local actual_items=0

    if command -v jq &>/dev/null; then
        while IFS= read -r line; do
            files+=("$line")
            ((actual_items++))
        done < <(echo "$trash_json" | jq -r '.[] | "\(.index). \(.name)"')
    else
        local index=1
        if [[ "$TRASH_CMD" == "gio trash" ]]; then
            local trash_dir="$HOME/.local/share/Trash/files"
            if [[ -d "$trash_dir" ]]; then
                for item in "$trash_dir"/*; do
                    if [[ -e "$item" ]]; then
                        local filename=$(basename "$item")
                        files+=("$index. $filename")
                        ((index++))
                        ((actual_items++))
                    fi
                done
            fi
        elif [[ "$TRASH_CMD" == "trash-put" ]] && command -v trash-list &>/dev/null; then
            while IFS= read -r line; do
                if [[ -n "$line" ]]; then
                    local filename=$(echo "$line" | awk '{$1=$2=""; print substr($0,3)}' | sed 's/^ *//' | xargs basename)
                    files+=("$index. $filename")
                    ((index++))
                    ((actual_items++))
                fi
            done < <(trash-list 2>/dev/null)
        fi
    fi

    if [[ ${actual_items} -eq 0 ]]; then
        echo -e "${gl_huang}回收站为空${gl_bai}"
        return
    fi

    local count=0
    local items_per_line=4 # 每行显示4个项目
    local max_length=0

    for file in "${files[@]}"; do
        local len=${#file}
        if [ "$len" -gt "$max_length" ]; then
            max_length=$len
        fi
    done

    max_length=$((max_length + 4)) # 增加一些间距

    for i in "${!files[@]}"; do
        count=$((count + 1))
        printf "${gl_bufan}%2d.${gl_bai} %-${max_length}s" "$count" "${files[i]#*. }"

        if [ $((count % items_per_line)) -eq 0 ]; then
            echo ""
        fi
    done

    if [ $((count % items_per_line)) -ne 0 ]; then
        echo ""
    fi

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

    echo -e "${gl_huang}统计信息:${gl_bai}"

    if [[ "$TRASH_CMD" == "gio trash" ]]; then
        local trash_dir="$HOME/.local/share/Trash/files"
        if [[ -d "$trash_dir" ]]; then
            total_files=0
            total_dirs=0

            for item in "$trash_dir"/*; do
                if [[ -e "$item" ]]; then
                    if [[ -f "$item" ]] || [[ -L "$item" ]]; then
                        ((total_files++))
                    elif [[ -d "$item" ]]; then
                        ((total_dirs++))
                    fi
                fi
            done

            if [[ $total_files -gt 0 || $total_dirs -gt 0 ]]; then
                total_size=$(du -sb "$trash_dir" 2>/dev/null | cut -f1)
                if [[ $total_size -ge 1073741824 ]]; then
                    total_size_display=$(echo "scale=2; $total_size / 1073741824" | bc 2>/dev/null)GB
                elif [[ $total_size -ge 1048576 ]]; then
                    total_size_display=$(echo "scale=2; $total_size / 1048576" | bc 2>/dev/null)MB
                elif [[ $total_size -ge 1024 ]]; then
                    total_size_display=$(echo "scale=2; $total_size / 1024" | bc 2>/dev/null)KB
                else
                    total_size_display="${total_size}B"
                fi
            fi

            echo -e "  ${gl_bai}项目总数:${gl_bai} ${gl_huang}${actual_items}${gl_bai}"
            echo -e "  ${gl_bai}文件数量:${gl_bai} ${gl_huang}${total_files}${gl_bai}"
            echo -e "  ${gl_bai}目录数量:${gl_bai} ${gl_huang}${total_dirs}${gl_bai}"
            if [[ -n "$total_size_display" ]]; then
                echo -e "  ${gl_bai}大小总计:${gl_bai} ${gl_huang}${total_size_display}${gl_bai}"
            fi
        fi
    elif [[ "$TRASH_CMD" == "trash-put" ]]; then
        local trash_dir=""
        local trash_paths=(
            "$HOME/.local/share/Trash/files"
            "$HOME/.local/share/trash/files"
            "/tmp/.Trash-$(id -u)/files"
        )

        for trash_path in "${trash_paths[@]}"; do
            if [[ -d "$trash_path" ]]; then
                trash_dir="$trash_path"
                break
            fi
        done

        if [[ -n "$trash_dir" ]] && [[ -d "$trash_dir" ]]; then
            total_files=0
            total_dirs=0

            for item in "$trash_dir"/*; do
                if [[ -e "$item" ]]; then
                    if [[ -f "$item" ]] || [[ -L "$item" ]]; then
                        ((total_files++))
                    elif [[ -d "$item" ]]; then
                        ((total_dirs++))
                    fi
                fi
            done

            if [[ $total_files -gt 0 || $total_dirs -gt 0 ]]; then
                total_size=$(du -sb "$trash_dir" 2>/dev/null | cut -f1)
                if [[ $total_size -ge 1073741824 ]]; then
                    total_size_display=$(echo "scale=2; $total_size / 1073741824" | bc 2>/dev/null)GB
                elif [[ $total_size -ge 1048576 ]]; then
                    total_size_display=$(echo "scale=2; $total_size / 1048576" | bc 2>/dev/null)MB
                elif [[ $total_size -ge 1024 ]]; then
                    total_size_display=$(echo "scale=2; $total_size / 1024" | bc 2>/dev/null)KB
                else
                    total_size_display="${total_size}B"
                fi
            fi

            echo -e "  ${gl_bufan}项目总数:${gl_bai} ${gl_huang}${actual_items}${gl_bai}"
            echo -e "  ${gl_bufan}文件数量:${gl_bai} ${gl_huang}${total_files}${gl_bai}"
            echo -e "  ${gl_bufan}目录数量:${gl_bai} ${gl_huang}${total_dirs}${gl_bai}"
            if [[ -n "$total_size_display" ]]; then
                echo -e "  ${gl_bufan}总大小:${gl_bai} ${gl_huang}${total_size_display}${gl_bai}"
            fi
        else
            if command -v trash-list &>/dev/null; then
                local trash_output=$(trash-list 2>/dev/null)
                if [[ -n "$trash_output" ]]; then
                    local line_count=$(echo "$trash_output" | wc -l)
                    echo -e "  ${gl_bufan}项目总数:${gl_bai} ${gl_huang}${line_count}${gl_bai}"

                    for trash_path in "$HOME/.local/share/Trash" "$HOME/.local/share/trash"; do
                        if [[ -d "$trash_path/files" ]]; then
                            total_size=$(du -sb "$trash_path/files" 2>/dev/null | cut -f1)
                            if [[ -n "$total_size" ]] && [[ $total_size -gt 0 ]]; then
                                if [[ $total_size -ge 1073741824 ]]; then
                                    total_size_display=$(echo "scale=2; $total_size / 1073741824" | bc 2>/dev/null)GB
                                elif [[ $total_size -ge 1048576 ]]; then
                                    total_size_display=$(echo "scale=2; $total_size / 1048576" | bc 2>/dev/null)MB
                                elif [[ $total_size -ge 1024 ]]; then
                                    total_size_display=$(echo "scale=2; $total_size / 1024" | bc 2>/dev/null)KB
                                else
                                    total_size_display="${total_size}B"
                                fi
                                echo -e "  ${gl_bufan}总大小:${gl_bai} ${gl_huang}${total_size_display}${gl_bai}"
                                break
                            fi
                        fi
                    done
                fi
            else
                echo -e "  ${gl_bufan}项目总数:${gl_bai} ${gl_huang}${actual_items}${gl_bai}"
                echo -e "  ${gl_huang}(无法获取详细统计信息)${gl_bai}"
            fi
        fi
    fi

}

TRASH_CONFIG_FILE="$HOME/.trash_config"

save_trash_config() {
    local config_content=""
    if [[ -n "$TRASH_CMD" ]]; then
        config_content="TRASH_CMD=\"$TRASH_CMD\""
    else
        config_content="TRASH_CMD=\"\""
    fi

    echo "# 回收站配置文件" >"$TRASH_CONFIG_FILE"
    echo "# 最后更新时间: $(date '+%Y-%m-%d %H:%M:%S')" >>"$TRASH_CONFIG_FILE"
    echo "" >>"$TRASH_CONFIG_FILE"
    echo "$config_content" >>"$TRASH_CONFIG_FILE"

    chmod 600 "$TRASH_CONFIG_FILE" 2>/dev/null
}

load_trash_config() {
    if [[ -f "$TRASH_CONFIG_FILE" ]]; then
        source "$TRASH_CONFIG_FILE" 2>/dev/null || {
            echo -e "${gl_huang}回收站配置文件加载失败,将重新检测${gl_bai}"
            TRASH_CMD=""
        }

        if [[ -n "$TRASH_CMD" ]]; then
            if [[ "$TRASH_CMD" == "gio trash" ]]; then
                if ! command -v gio &>/dev/null; then
                    echo -e "${gl_huang}配置的回收站工具 gio 不可用,重新检测${gl_bai}"
                    TRASH_CMD=""
                fi
            elif [[ "$TRASH_CMD" == "trash-put" ]]; then
                if ! command -v trash-put &>/dev/null; then
                    echo -e "${gl_huang}配置的回收站工具 trash-put 不可用,重新检测${gl_bai}"
                    TRASH_CMD=""
                fi
            else
                if ! eval "$TRASH_CMD --help" &>/dev/null && ! eval "$TRASH_CMD -h" &>/dev/null; then
                    echo -e "${gl_huang}配置的回收站工具可能不可用,重新检测${gl_bai}"
                    TRASH_CMD=""
                fi
            fi
        fi
    else
        TRASH_CMD=""
    fi
}

install_trash() {
    local trash_cmd=""

    load_trash_config

    if [[ -n "$TRASH_CMD" ]]; then
        echo -e "${gl_lv}已加载回收站配置: $TRASH_CMD${gl_bai}"
        return 0
    fi

    if command -v trash-put &>/dev/null; then
        trash_cmd="trash-put"
        echo -e "${gl_lv}检测到已安装 trash-cli 回收站工具${gl_bai}"
    elif command -v gio &>/dev/null; then
        trash_cmd="gio trash"
        echo -e "${gl_lv}检测到已安装 gio 回收站工具${gl_bai}"
    else
        log_warn "未找到回收站工具,正在尝试安装${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"

        if command -v apt &>/dev/null; then
            log_warn "${gl_lan}检测到 Debian/Ubuntu 系统,安装 trash-cli${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
            sudo apt update && sudo apt install -y trash-cli
            if command -v trash-put &>/dev/null; then
                trash_cmd="trash-put"
            fi
        elif command -v yum &>/dev/null; then
            log_warn "${gl_lan}检测到 CentOS/RHEL 系统,安装 trash-cli${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
            sudo yum install -y trash-cli
            if command -v trash-put &>/dev/null; then
                trash_cmd="trash-put"
            fi
        elif command -v dnf &>/dev/null; then
            log_warn "${gl_lan}检测到 Fedora 系统,安装 trash-cli${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
            sudo dnf install -y trash-cli
            if command -v trash-put &>/dev/null; then
                trash_cmd="trash-put"
            fi
        elif command -v pacman &>/dev/null; then
            log_warn "${gl_lan}检测到 Arch Linux 系统,安装 trash-cli${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
            sudo pacman -S --noconfirm trash-cli
            if command -v trash-put &>/dev/null; then
                trash_cmd="trash-put"
            fi
        else
            log_error "${gl_hong}无法自动安装回收站工具,请手动安装 trash-cli${gl_bai}"
            return 1
        fi
    fi

    if [[ -n "$trash_cmd" ]]; then
        TRASH_CMD="$trash_cmd"
        save_trash_config
        log_warn "回收站功能已启用并保存配置: ${gl_lv}$TRASH_CMD${gl_bai}"
        return 0
    else
        log_error "回收站工具安装失败"
        return 1
    fi
}

auto_setup_trash() {
    echo -e "${gl_zi}>>> 正在自动初始化回收站${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    if [[ -z "$TRASH_CMD" ]]; then
        if install_trash; then
            log_ok "回收站初始化成功"
        else
            log_error "回收站初始化失败"
            exit_animation
            return 1
        fi
    else
        echo -e "${gl_lv}回收站已初始化: $TRASH_CMD${gl_bai}"
    fi

    local user_shell=$(basename "$SHELL")
    local config_file=""

    case "$user_shell" in
    bash)
        config_file="$HOME/.bashrc"
        ;;
    zsh)
        config_file="$HOME/.zshrc"
        ;;
    *)
        log_error "不支持的shell: $user_shell,跳过rm重定向配置"
        return 0
        ;;
    esac

    if grep -q "alias rm=" "$config_file" 2>/dev/null; then
        echo -e "${gl_huang}rm重定向已配置,无需重复配置${gl_bai}"
        return 0
    fi

    echo -e ""
    echo -e "${gl_zi}>>> 正在自动配置${gl_huang}rm${gl_zi}命令重定向到回收站${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    echo "" >>"$config_file"
    echo "# 自动配置:rm命令重定向到回收站" >>"$config_file"
    echo "# 配置时间: $(date '+%Y-%m-%d %H:%M:%S')" >>"$config_file"
    echo "alias rm='$TRASH_CMD'" >>"$config_file"
    echo "" >>"$config_file"

    if [[ $? -eq 0 ]]; then
        log_ok "${gl_huang}rm${gl_bai}重定向配置成功"
        log_warn "配置已添加到: ${gl_huang}$config_file${gl_bai}"
        log_warn "请重新登录或运行: ${gl_huang}source $config_file 使配置生效${gl_bai}"

        alias rm='$TRASH_CMD' 2>/dev/null
        log_ok "已为当前${gl_bufan}shell${gl_bai} 设置 ${gl_huang} rm ${gl_bai}别名"

        return 0
    else
        echo -e "${gl_hong}rm${gl_bai}重定向配置失败"
        exit_animation
        return 1
    fi
}

delete_file_with_trash() {
    local file="${1:-}"

    if [[ -z "$file" ]]; then
        echo -e "${gl_hong}错误:文件名参数为空${gl_bai}"
        return 1
    fi

    if [[ -z "$TRASH_CMD" ]]; then
        echo -e "${gl_huang}回收站未初始化,尝试自动安装${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
        install_trash || {
            echo -e "${gl_hong}回收站安装失败,将使用直接删除${gl_bai}"
            return 1
        }
    fi

    if [[ -e "$file" ]]; then
        echo -e ""
        echo -e "${gl_huang}正在移动到回收站: ${gl_lv}$file${gl_bai}"

        if eval "$TRASH_CMD \"$file\"" 2>/dev/null; then
            echo -e "${gl_lv}${gl_bai}已移动到回收站: ${gl_lv}$file${gl_bai}"
            return 0
        else
            local error_msg
            error_msg=$(eval "$TRASH_CMD \"$file\"" 2>&1)

            if echo "$error_msg" | grep -q "不支持在系统内部挂载上的丢弃到回收站操作" ||
                echo "$error_msg" | grep -qi "not supported.*trash" ||
                echo "$error_msg" | grep -qi "cannot trash.*mount" ||
                echo "$error_msg" | grep -qi "cannot move to trash" ||
                echo "$error_msg" | grep -qi "trash not available"; then

                echo -e "${gl_huang}⚠ 此位置不支持回收站,将使用直接删除${gl_bai}"
                echo -e "${gl_lan}正在直接删除: $file${gl_bai}"

                if [[ -d "$file" ]]; then
                    if rm -rf "$file" 2>/dev/null; then
                        echo -e "${gl_lv}${gl_bai}已直接删除目录: ${gl_huang}$file${gl_bai}"
                        return 0
                    else
                        echo -e "${gl_hong}${gl_bai}直接删除目录失败: ${gl_huang}$file${gl_bai}"
                        return 1
                    fi
                else
                    if rm -f "$file" 2>/dev/null; then
                        echo -e "${gl_lv}${gl_bai}已直接删除文件: ${gl_huang}$file${gl_bai}"
                        return 0
                    else
                        echo -e "${gl_hong}${gl_bai}直接删除文件失败: ${gl_huang}$file${gl_bai}"
                        return 1
                    fi
                fi
            else
                echo -e "${gl_hong}${gl_bai}移动到回收站失败: ${gl_huang}$file${gl_bai}"
                echo -e "${gl_hui}错误信息: $error_msg${gl_bai}"
                return 1
            fi
        fi
    else
        echo -e "${gl_huang}文件不存在: $file${gl_bai}"
        return 1
    fi
}

get_trash_list() {
    local trash_items=()

    if [[ -z "$TRASH_CMD" ]]; then
        echo "[]"
        return
    fi

    if [[ "$TRASH_CMD" == "gio trash" ]]; then
        local trash_dir="$HOME/.local/share/Trash"
        if [[ -d "$trash_dir/files" ]]; then
            local count=1
            for item in "$trash_dir/files"/*; do
                if [[ -e "$item" ]]; then
                    local filename=$(basename "$item")
                    local info_file="$trash_dir/info/${filename}.trashinfo"
                    local original_path=""
                    local deletion_date=""

                    if [[ -f "$info_file" ]]; then
                        original_path=$(grep "^Path=" "$info_file" | cut -d= -f2-)
                        deletion_date=$(grep "^DeletionDate=" "$info_file" | cut -d= -f2-)
                    fi

                    trash_items+=("{\"index\":$count,\"name\":\"$filename\",\"original_path\":\"$original_path\",\"deletion_date\":\"$deletion_date\"}")
                    ((count++))
                fi
            done
        fi
    elif [[ "$TRASH_CMD" == "trash-put" ]] && command -v trash-list &>/dev/null; then
        local count=1
        while IFS= read -r line; do
            if [[ -n "$line" ]]; then
                local deletion_date=$(echo "$line" | awk '{print $1 " " $2}')
                local original_path=$(echo "$line" | awk '{$1=$2=""; print substr($0,3)}' | sed 's/^ *//')
                local filename=$(basename "$original_path")

                trash_items+=("{\"index\":$count,\"name\":\"$filename\",\"original_path\":\"$original_path\",\"deletion_date\":\"$deletion_date\"}")
                ((count++))
            fi
        done < <(trash-list 2>/dev/null)
    fi

    if [[ ${#trash_items[@]} -eq 0 ]]; then
        echo "[]"
    else
        echo "[$(
            IFS=,
            echo "${trash_items[*]}"
        )]"
    fi
}

enable_trash() {
    echo
    echo -e "${gl_zi}>>> 启用回收站${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    load_trash_config

    if [[ -n "$TRASH_CMD" ]]; then
        echo -e "${gl_lv}回收站已经启用${gl_bai}"
        echo -e "${gl_bufan}当前回收站工具: ${gl_lv}$TRASH_CMD${gl_bai}"
    else
        if install_trash; then
            echo -e "${gl_lv}回收站启用成功${gl_bai}"
        else
            echo -e "${gl_hong}回收站启用失败${gl_bai}"
        fi
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    exit_animation
    return 1
}

disable_trash() {
    echo
    echo -e "${gl_zi}>>> 关闭回收站${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    if [[ -n "$TRASH_CMD" ]]; then
        TRASH_CMD=""
        save_trash_config
        echo -e "${gl_lv}回收站已关闭${gl_bai}"
        echo -e "${gl_huang}现在删除文件将直接永久删除,请谨慎操作!${gl_bai}"
    else
        echo -e "${gl_huang}回收站已经是关闭状态${gl_bai}"
    fi

    echo
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    exit_animation
    return 1
}

empty_trash() {
    echo
    echo -e "${gl_zi}>>> 清空回收站${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    if [[ -z "$TRASH_CMD" ]]; then
        echo -e "${gl_hong}回收站未启用${gl_bai}"
        exit_animation
        return
    fi

    if [[ "$TRASH_CMD" == "gio trash" ]]; then
        local trash_dir="$HOME/.local/share/Trash"
        if [[ -d "$trash_dir" ]]; then
            rm -rf "$trash_dir/files/"* 2>/dev/null
            rm -rf "$trash_dir/info/"* 2>/dev/null
            echo -e "${gl_lv}回收站已清空${gl_bai}"
        else
            echo -e "${gl_huang}回收站目录不存在${gl_bai}"
        fi
    elif [[ "$TRASH_CMD" == "trash-put" ]]; then
        if command -v trash-empty &>/dev/null; then
            trash-empty
            echo -e "${gl_lv}回收站已清空${gl_bai}"
        else
            echo -e "${gl_hong}trash-empty 命令不可用${gl_bai}"
        fi
    else
        echo -e "${gl_hong}不支持的回收站工具: $TRASH_CMD${gl_bai}"
    fi

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    exit_animation
    return 1
}

restore_trash_interactive() {
    echo
    echo -e "${gl_zi}>>> 恢复回收站文件${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    if [[ -z "$TRASH_CMD" ]]; then
        echo -e "${gl_hong}回收站未启用${gl_bai}"
        exit_animation
        return
    fi

    local trash_json=$(get_trash_list)
    local item_count=0

    if command -v jq &>/dev/null; then
        item_count=$(echo "$trash_json" | jq length)
    else
        item_count=$(echo "$trash_json" | grep -o '"index"' | wc -l)
    fi

    if [[ $item_count -eq 0 ]]; then
        echo -e "${gl_huang}回收站为空,没有文件可恢复${gl_bai}"
        exit_animation
        return
    fi

    echo -e "${gl_bufan}可恢复的文件:${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    if command -v jq &>/dev/null; then
        echo "$trash_json" | jq -r '.[] | "\(.index). \(.name)"' | while read -r line; do
            local index=$(echo "$line" | cut -d. -f1)
            local filename=$(echo "$line" | cut -d. -f2- | sed 's/^ *//')
            echo -e "  ${gl_huang}$index.${gl_bai} $filename"
        done
    else
        local index=1
        if [[ "$TRASH_CMD" == "gio trash" ]]; then
            local trash_dir="$HOME/.local/share/Trash/files"
            for item in "$trash_dir"/*; do
                if [[ -e "$item" ]]; then
                    local filename=$(basename "$item")
                    echo -e "  ${gl_huang}$index.${gl_bai} $filename"
                    ((index++))
                fi
            done
        elif [[ "$TRASH_CMD" == "trash-put" ]] && command -v trash-list &>/dev/null; then
            trash-list | while read -r line; do
                if [[ -n "$line" ]]; then
                    local filename=$(echo "$line" | awk '{$1=$2=""; print substr($0,3)}' | sed 's/^ *//' | xargs basename)
                    echo -e "  ${gl_huang}$index.${gl_bai} $filename"
                    ((index++))
                fi
            done
        fi
    fi

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_huang}提示:可输入多个序号,用空格分隔;0 或留空取消${gl_bai}"

    echo -ne "${gl_bufan}请输入要恢复的文件序号: ${gl_bai}"
    read -r -e raw
    [[ -z "$raw" || "$raw" == "0" ]] && return

    local to_restore=()
    read -r -ra tokens <<<"$raw"

    for tok in "${tokens[@]}"; do
        [[ -z "$tok" ]] && continue

        if [[ $tok =~ ^[0-9]+$ ]] && ((tok >= 1 && tok <= item_count)); then
            to_restore+=("$tok")
        else
            echo -e "${gl_hong}跳过无效序号: $tok${gl_bai}"
        fi
    done

    ((${#to_restore[@]} == 0)) && {
        echo -e "${gl_huang}没有选择有效的文件序号,取消恢复${gl_bai}"
        exit_animation
        return
    }

    echo
    echo -e "${gl_hong}即将恢复以下 ${#to_restore[@]} 个文件:${gl_bai}"
    for index in "${to_restore[@]}"; do
        if command -v jq &>/dev/null; then
            local filename=$(echo "$trash_json" | jq -r ".[] | select(.index==$index) | .name")
            echo -e "  ${gl_huang}$index. $filename${gl_bai}"
        else
            echo -e "  ${gl_huang}$index. 文件${gl_bai}"
        fi
    done

    read -r -e -p "$(echo -e "${gl_bai}确认恢复这些文件? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" -n1 -r
    echo
    [[ $REPLY =~ ^[Yy]$ ]] || return

    local ok=0 fail=0
    for index in "${to_restore[@]}"; do
        if restore_single_file "$index"; then
            ((ok++))
        else
            ((fail++))
        fi
    done

    echo
    if ((ok > 0)); then
        echo -e "${gl_lv}✓ 成功恢复 $ok 个文件${gl_bai}"
    fi
    if ((fail > 0)); then
        echo -e "${gl_hong}$fail 个文件恢复失败${gl_bai}"
    fi

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

restore_single_file() {
    local index="${1:-}"

    if [[ "$TRASH_CMD" == "gio trash" ]]; then
        local trash_dir="$HOME/.local/share/Trash"
        local files_dir="$trash_dir/files"
        local info_dir="$trash_dir/info"

        local filename=""
        local count=1
        for item in "$files_dir"/*; do
            if [[ -e "$item" ]]; then
                if [[ $count -eq $index ]]; then
                    filename=$(basename "$item")
                    break
                fi
                ((count++))
            fi
        done

        if [[ -z "$filename" ]]; then
            echo -e "${gl_hong}无法找到文件: 序号 $index${gl_bai}"
            exit_animation
            return 1
        fi

        local file_path="$files_dir/$filename"
        local info_file="$info_dir/${filename}.trashinfo"
        local original_path=""

        if [[ -f "$info_file" ]]; then
            original_path=$(grep "^Path=" "$info_file" | cut -d= -f2-)
        fi

        if [[ -n "$original_path" && -e "$file_path" ]]; then
            local target_dir=$(dirname "$original_path")
            mkdir -p "$target_dir"

            if mv "$file_path" "$original_path" 2>/dev/null; then
                rm -f "$info_file"
                echo -e "${gl_lv}✓ 已恢复: $filename${gl_bai}"
                return 0
            else
                echo -e "${gl_hong}✗ 恢复失败: $filename${gl_bai}"
                exit_animation
                return 1
            fi
        else
            echo -e "${gl_hong}✗ 文件信息不完整: $filename${gl_bai}"
            exit_animation
            return 1
        fi

    elif [[ "$TRASH_CMD" == "trash-put" ]]; then
        if command -v trash-restore &>/dev/null; then
            echo -e "${gl_huang}请手动在接下来的界面中选择要恢复的文件${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
            trash-restore
            return $?
        else
            echo -e "${gl_hong}trash-restore 命令不可用${gl_bai}"
            exit_animation
            return 1
        fi
    else
        echo -e "${gl_hong}不支持的回收站工具${gl_bai}"
        exit_animation
        return 1
    fi
}

refresh_trash() {
    echo
    echo -e "${gl_zi}>>> 刷新回收站状态${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    load_trash_config

    if [[ -n "$TRASH_CMD" ]]; then
        echo -e "${gl_lv}✓ 回收站状态已刷新${gl_bai}"
        echo -e "${gl_bufan}当前回收站工具: ${gl_lv}$TRASH_CMD${gl_bai}"
    else
        echo -e "${gl_hong}回收站功能不可用${gl_bai}"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    exit_animation
    return 1
}

test_trash_function() {
    echo
    echo -e "${gl_zi}>>> 测试回收站功能${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    if [[ -z "$TRASH_CMD" ]]; then
        echo -e "${gl_hong}回收站未启用${gl_bai}"
        exit_animation
        return
    fi

    local test_file="trash_test_$(date +%s).sh"
    echo -e "${gl_huang}创建测试文件: $test_file${gl_bai}"
    touch "$test_file"

    if [[ -e "$test_file" ]]; then
        echo -e "${gl_lv}测试文件创建成功${gl_bai}"
        echo -e "${gl_huang}尝试移动到回收站${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"

        if delete_file_with_trash "$test_file"; then
            echo -e "${gl_lv}测试成功:文件已移动到回收站${gl_bai}"
        else
            echo -e "${gl_hong}测试失败:文件未能移动到回收站${gl_bai}"
        fi
    else
        echo -e "${gl_hong}测试文件创建失败${gl_bai}"
    fi

    local test_folder="trash_test_folder_$(date +%s)"
    echo -e "${gl_huang}创建测试文件夹: $test_folder${gl_bai}"
    mkdir -p "$test_folder"

    if [[ -d "$test_folder" ]]; then
        echo -e "${gl_lv}测试文件夹创建成功${gl_bai}"
        echo -e "${gl_huang}尝试将文件夹移动到回收站${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"

        if delete_file_with_trash "$test_folder"; then
            echo -e "${gl_lv}测试成功:文件夹已移动到回收站${gl_bai}"
        else
            echo -e "${gl_hong}测试失败:文件夹未能移动到回收站${gl_bai}"
            rmdir "$test_folder" 2>/dev/null
        fi
    else
        echo -e "${gl_hong}测试文件夹创建失败${gl_bai}"
    fi

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

setup_rm_redirect() {
    echo
    echo -e "${gl_zi}=== 配置 rm 命令重定向到回收站 ===${gl_bai}"

    if [[ -z "$TRASH_CMD" ]]; then
        echo -e "${gl_hong}回收站未启用,请先启用回收站${gl_bai}"
        exit_animation
        return
    fi

    echo -e "${gl_huang}此功能将创建一个别名,将 rm 命令重定向到回收站${gl_bai}"
    echo -e "${gl_huang}这样使用 rm 删除的文件也会进入回收站${gl_bai}"
    echo
    echo -e "${gl_hong}警告:这可能会影响系统脚本和其他应用程序的行为${gl_bai}"
    echo -e "${gl_huang}建议仅在交互式shell中使用此功能${gl_bai}"
    echo

    read -r -e -p "$(echo -e "${gl_bai}确认配置 rm 命令重定向? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" -n1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        echo -e "${gl_huang}已取消配置${gl_bai}"
        return
    fi

    local user_shell=$(basename "$SHELL")
    local config_file=""

    case "$user_shell" in
    bash)
        config_file="$HOME/.bashrc"
        ;;
    zsh)
        config_file="$HOME/.zshrc"
        ;;
    *)
        echo -e "${gl_hong}不支持的shell: $user_shell${gl_bai}"
        echo -e "${gl_huang}请手动在您的shell配置文件中添加以下别名:${gl_bai}"
        echo "alias rm='$TRASH_CMD'"
        echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
        read -r -n1 -s
        return
        ;;
    esac

    if grep -q "alias rm=" "$config_file" 2>/dev/null; then
        echo -e "${gl_huang}检测到已存在 rm 别名配置${gl_bai}"
        echo -e "${gl_huang}当前配置: $(grep "alias rm=" "$config_file")${gl_bai}"

        read -r -e -p "$(echo -e "${gl_bai}是否覆盖现有配置? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" -n1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            echo -e "${gl_huang}已取消配置${gl_bai}"
            return
        fi

        sed -i '/alias rm=/d' "$config_file"
    fi

    echo "# 配置rm命令重定向到回收站" >>"$config_file"
    echo "# 配置时间: $(date '+%Y-%m-%d %H:%M:%S')" >>"$config_file"
    echo "alias rm='$TRASH_CMD'" >>"$config_file"

    if [[ $? -eq 0 ]]; then
        echo -e "${gl_lv}✓ 已成功配置 rm 命令重定向${gl_bai}"
        echo -e "${gl_huang}配置已添加到: $config_file${gl_bai}"
        echo -e "${gl_huang}请重新登录或运行: source $config_file${gl_bai}"
        echo
        echo -e "${gl_lv}现在使用 rm 命令删除的文件将进入回收站${gl_bai}"
    else
        echo -e "${gl_hong}✗ 配置失败${gl_bai}"
    fi

    echo
    echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
    read -r -n1 -s
}

remove_rm_redirect() {
    echo
    echo -e "${gl_zi}=== 移除 rm 命令重定向 ===${gl_bai}"

    local user_shell=$(basename "$SHELL")
    local config_file=""

    case "$user_shell" in
    bash)
        config_file="$HOME/.bashrc"
        ;;
    zsh)
        config_file="$HOME/.zshrc"
        ;;
    *)
        echo -e "${gl_hong}不支持的shell: $user_shell${gl_bai}"
        echo -e "${gl_huang}请手动从您的shell配置文件中移除 rm 别名${gl_bai}"
        echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
        read -r -n1 -s
        return
        ;;
    esac

    if grep -q "alias rm=" "$config_file" 2>/dev/null; then
        echo -e "${gl_huang}检测到 rm 别名配置: $(grep "alias rm=" "$config_file")${gl_bai}"

        read -r -e -p "$(echo -e "${gl_bai}确认移除 rm 命令重定向? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" -n1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            echo -e "${gl_huang}已取消操作${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
            exit_animation
            return
        fi

        sed -i '/alias rm=/d' "$config_file"

        if [[ $? -eq 0 ]]; then
            echo -e "${gl_lv}✓ 已成功移除 rm 命令重定向${gl_bai}"
            echo -e "${gl_huang}请重新登录或运行: source $config_file${gl_bai}"
            echo
            echo -e "${gl_lv}现在 rm 命令将恢复为系统默认行为${gl_bai}"
        else
            echo -e "${gl_hong}✗ 移除失败${gl_bai}"
        fi
    else
        echo -e "${gl_huang}未找到 rm 命令重定向配置${gl_bai}"
    fi

    echo
    echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    read -r -n1 -s
}

check_rm_redirect() {
    echo
    echo -e "${gl_zi}=== rm 命令重定向状态 ===${gl_bai}"

    local user_shell=$(basename "$SHELL")
    local config_file=""

    case "$user_shell" in
    bash)
        config_file="$HOME/.bashrc"
        ;;
    zsh)
        config_file="$HOME/.zshrc"
        ;;
    *)
        echo -e "${gl_hong}不支持的shell: $user_shell${gl_bai}"
        return
        ;;
    esac

    if grep -q "alias rm=" "$config_file" 2>/dev/null; then
        echo -e "${gl_lv}✓ rm 命令重定向已启用${gl_bai}"
        echo -e "${gl_huang}当前配置: $(grep "alias rm=" "$config_file")${gl_bai}"
        echo
        echo -e "${gl_lv}使用 rm 命令删除的文件将进入回收站${gl_bai}"
    else
        echo -e "${gl_huang}✗ rm 命令重定向未启用${gl_bai}"
        echo
        echo -e "${gl_huang}使用 rm 命令删除的文件将永久删除${gl_bai}"
        echo -e "${gl_huang}不会进入回收站${gl_bai}"
    fi

    echo
    echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    read -r -n1 -s
}

remove_rm_redirect_silent() {
    local user_shell=$(basename "$SHELL")
    local config_file=""

    case "$user_shell" in
    bash)
        config_file="$HOME/.bashrc"
        ;;
    zsh)
        config_file="$HOME/.zshrc"
        ;;
    *)
        return
        ;;
    esac

    if grep -q "alias rm=" "$config_file" 2>/dev/null; then
        sed -i '/alias rm=/d' "$config_file"
    fi
}

uninstall_trash_tool() {
    clear
    echo
    echo -e "${gl_zi}>>> 卸载回收站工具${gl_bai}"
    if [[ -n "$TRASH_CMD" ]]; then
        echo -e "${gl_bufan}当前回收站工具: ${gl_lv}$TRASH_CMD${gl_bai}"
    fi
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    log_warn "此操作将卸载回收站工具并清理相关文件!"
    echo -e "${gl_huang}这将导致:${gl_bai}"
    echo -e "   ${gl_bufan}1. ${gl_bai}回收站工具将被卸载"
    echo -e "   ${gl_bufan}2. ${gl_bai}回收站中的文件将${gl_hong}永久丢失${gl_bai}"
    echo -e "   ${gl_bufan}3. ${gl_bai}rm重定向配置将被移除"
    echo -e "   ${gl_bufan}4. ${gl_bai}回收站相关目录可能被清理"
    echo -e "   ${gl_bufan}5. ${gl_bai}回收站配置文件将被删除"

    local has_files=false
    if [[ "$TRASH_CMD" == "gio trash" ]]; then
        local trash_dir="$HOME/.local/share/Trash/files"
        if [[ -d "$trash_dir" ]] && [[ -n "$(ls -A "$trash_dir" 2>/dev/null)" ]]; then
            has_files=true
            echo -e "${gl_hong}回收站中有文件,卸载前建议先清空回收站!${gl_bai}"
        fi
    elif [[ "$TRASH_CMD" == "trash-put" ]] && command -v trash-list &>/dev/null; then
        if [[ -n "$(trash-list 2>/dev/null)" ]]; then
            has_files=true
            echo -e "${gl_hong}回收站中有文件,卸载前建议先清空回收站!${gl_bai}"
        fi
    fi

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    read -r -e -p "$(echo -e "${gl_bai}确认要卸载回收站工具? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" -n1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        echo -e "${gl_huang}已取消卸载操作${gl_bai}"
        exit_animation
        return
    fi

    if [[ "$has_files" == "true" ]]; then
        echo
        read -r -e -p "$(echo -e "${gl_bai}回收站中仍有文件,确定要继续卸载吗? (${gl_lv}y${gl_bai}/${gl_hong}N${gl_bai}): ")" -n1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            echo -e "${gl_huang}已取消卸载操作${gl_bai}"
            exit_animation
            return
        fi
    fi

    local uninstall_success=false
    local cleanup_success=false

    clear
    echo
    echo -e "${gl_zi}>>> 正在卸载回收站工具${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    if command -v trash-put &>/dev/null; then
        echo -e "${gl_lan}检测到 trash-cli,正在卸载${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}${gl_bai}"

        if command -v apt &>/dev/null; then
            sudo apt remove -y trash-cli && uninstall_success=true
        elif command -v yum &>/dev/null; then
            sudo yum remove -y trash-cli && uninstall_success=true
        elif command -v dnf &>/dev/null; then
            sudo dnf remove -y trash-cli && uninstall_success=true
        elif command -v pacman &>/dev/null; then
            sudo pacman -R --noconfirm trash-cli && uninstall_success=true
        else
            echo -e "${gl_huang}无法自动卸载,请手动卸载 trash-cli${gl_bai}"
        fi

        if [[ -d "$HOME/.local/share/trash" ]]; then
            rm -rf "$HOME/.local/share/trash" 2>/dev/null
        fi
    fi

    if [[ "$TRASH_CMD" == "gio trash" ]] && command -v gio &>/dev/null; then
        echo -e "${gl_huang}注意:gio 是 glib 的一部分,通常不建议卸载${gl_bai}"
        echo -e "${gl_huang}将只清理回收站目录,不卸载 gio${gl_bai}"
    fi

    echo -e ""
    echo -e "${gl_zi}>>> 正在清理回收站目录${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local trash_dirs=(
        "$HOME/.local/share/Trash"
        "$HOME/.local/share/trash"
        "/tmp/.Trash-$(id -u)"
    )

    for dir in "${trash_dirs[@]}"; do
        if [[ -d "$dir" ]]; then
            log_info "清理目录: ${gl_huang}$dir${gl_bai}"
            rm -rf "$dir" 2>/dev/null && cleanup_success=true
        fi
    done

    log_info "正在移除rm重定向配置${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    remove_rm_redirect_silent

    log_info "正在清理配置文件${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"

    if [[ -f "$TRASH_CONFIG_FILE" ]]; then
        rm -f "$TRASH_CONFIG_FILE" && log_ok "删除回收站配置文件${gl_bai}"
    fi

    local shell_configs=(
        "$HOME/.bashrc"
        "$HOME/.bash_profile"
        "$HOME/.bash_aliases"
        "$HOME/.zshrc"
        "$HOME/.zprofile"
        "$HOME/.zsh_aliases"
    )

    for config in "${shell_configs[@]}"; do
        if [[ -f "$config" ]]; then
            sed -i '/alias trash=/d' "$config" 2>/dev/null
            sed -i '/alias rm=/d' "$config" 2>/dev/null
            sed -i '/# 回收站配置/d' "$config" 2>/dev/null
            sed -i '/# Trash configuration/d' "$config" 2>/dev/null
            sed -i '/# 自动配置:rm命令重定向到回收站/d' "$config" 2>/dev/null
            sed -i '/# 配置时间:/d' "$config" 2>/dev/null
        fi
    done

    unset TRASH_CMD

    if [[ "$uninstall_success" == "true" || "$cleanup_success" == "true" ]]; then
        log_ok "回收站工具卸载完成"
        echo
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_huang}以下操作已完成:${gl_bai}"
        echo -e "   ${gl_lv}${gl_bai}回收站工具已卸载"
        echo -e "   ${gl_lv}${gl_bai}回收站目录已清理"
        echo -e "   ${gl_lv}${gl_bai}rm重定向配置已移除"
        echo -e "   ${gl_lv}${gl_bai}配置文件已清理"
        echo -e "   ${gl_lv}${gl_bai}环境变量已清理"
    else
        echo -e "${gl_hong}⚠ 卸载过程中可能存在问题${gl_bai}"
        echo -e "${gl_huang}请检查:${gl_bai}"
        echo -e "  • 回收站工具是否已安装"
        echo -e "  • 是否有足够的权限"
        echo -e "  • 手动检查配置文件"
    fi

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
    read -r -n1 -s
}

one_click_auto_setup() {
    echo -e ""
    echo -e "${gl_zi}>>> 一键自动初始化和配置回收站${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}): ")" -n1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        echo -e "${gl_huang}已取消自动配置${gl_bai}"
        exit_animation
        return
    fi

    if auto_setup_trash; then
        echo -e "${gl_lv}✓ 回收站自动配置完成!${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_huang}已启用功能:${gl_bai}"
        echo -e "  ${gl_lv}${gl_bai}回收站工具已安装/初始化"
        echo -e "  ${gl_lv}${gl_bai}rm命令已重定向到回收站"
        echo -e "  ${gl_lv}${gl_bai}配置文件已更新"
        echo
        echo -e "${gl_huang}现在删除文件将进入回收站,可以通过回收站管理恢复文件。${gl_bai}"
    else
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_hong}✗ 回收站自动配置失败${gl_bai}"
        echo -e "${gl_huang}请检查:${gl_bai}"
        echo -e "  • 网络连接"
        echo -e "  • 系统包管理器"
        echo -e "  • 权限设置"
    fi

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}按任意键继续${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
    read -r -n1 -s
}

manage_trash_menu() {
    load_trash_config

    local user_shell=$(basename "$SHELL")
    local config_file=""

    case "$user_shell" in
    bash) config_file="$HOME/.bashrc" ;;
    zsh) config_file="$HOME/.zshrc" ;;
    esac

    local rm_configured=false
    if [[ -n "$config_file" ]] && grep -q "alias rm=" "$config_file" 2>/dev/null; then
        rm_configured=true
    fi

    if [[ "$rm_configured" == "false" ]]; then
        clear
        echo -e "${gl_zi}>>> 回收站管理${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_hong}检测到您的系统尚未配置回收站功能${gl_bai}"
        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}配置 ${gl_huang}rm${gl_bai} 命令重定向到回收站"
        echo -e "   ${gl_bufan}4. ${gl_bai}更新 ${gl_huang}shell${gl_bai} 配置文件"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_hong}注意:配置后,使用 ${gl_huang}rm${gl_hong} 命令删除的文件将进入回收站而非永久删除${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}): ")" -n1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            auto_setup_trash
            echo
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_bai}按任意键进入回收站管理菜单${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
            read -r -n1 -s
        fi
    fi

    while true; do
        clear
        echo -e "${gl_zi}>>> 回收站管理${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

        if [[ -n "$TRASH_CMD" ]]; then
            echo -e "${gl_bufan}回收站状态: ${gl_lv}已启用 (${gl_huang}$TRASH_CMD)${gl_bai}"
        else
            echo -e "${gl_bufan}回收站状态: ${gl_hui}未启用${gl_bai}"
        fi

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

        show_trash_contents_and_stats

        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_lv}66. ${gl_bai}初始化回收站          ${gl_hong}99. ${gl_bai}卸载回收站"
        echo -e "${gl_huang}0.  ${gl_bai}返回上一级选单        ${gl_hong}00. ${gl_bai}退出脚本"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        read -r -e -p "请输入你的选择: " sub_choice
        case $sub_choice in
        1) disable_trash ;;
        2) enable_trash ;;
        3) empty_trash ;;
        4) restore_trash_interactive ;;
        5) refresh_trash ;;
        6) test_trash_function ;;
        66) one_click_auto_setup ;;
        99) uninstall_trash_tool ;;
        0) cancel_return; break ;;
        00 | 000 | 0000) save_trash_config; exit_script ;;
        *) handle_invalid_input ;;
        esac
    done
}

linux_file() {
    local title="${1:-文件管理器}"
    local menu_name="${2:-上一级选单}"
    
    # 如果第一个参数是目录,直接使用它
    if [[ -d "${1:-}" ]] && [[ "${1:-}" != "." ]]; then
        cd "$1" 2>/dev/null || true
        title="${2:-文件管理器}"
        menu_name="${3:-上一级选单}"
    fi

    root_use
    while true; do
        clear
        local current_dir="$(pwd)"
        if [ -z "$(ls -A "$current_dir" 2>/dev/null)" ]; then
            echo -e "${gl_huang}>>> 当前目录文件列表:${gl_bai}(${gl_lv}$current_dir${gl_bai})"
            echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
            echo -e "${gl_huang}当前目录为空${gl_bai}"
        else
            list_dir_colorful 0 4
        fi
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e ""
        echo -e "${gl_zi}>>> ${title}${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_bufan}目录操作 ${gl_huang}${gl_bai}"
        echo -e "${gl_bufan}1.  ${gl_bai}进入目录  ${gl_bufan}2.  ${gl_bai}创建目录   ${gl_bufan}3.  ${gl_bai}修改目录权限"
        echo -e "${gl_bufan}4.  ${gl_bai}改目录名  ${gl_bufan}5.  ${gl_bai}删除目录   ${gl_bufan}6.  ${gl_bai}返回上一级目录"
        echo -e "${gl_bufan}7.  ${gl_bai}搜索目录  ${gl_bufan}8.  ${gl_bai}查找大目录 ${gl_bufan}9.  ${gl_bai}列出目录大小"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_bufan}文件操作 ${gl_huang}${gl_bai}"
        echo -e "${gl_bufan}11. ${gl_bai}创建文件  ${gl_bufan}12. ${gl_bai}编辑文件   ${gl_bufan}13. ${gl_bai}修改文件权限"
        echo -e "${gl_bufan}14. ${gl_bai}改文件名  ${gl_bufan}15. ${gl_bai}删除文件   ${gl_bufan}16. ${gl_bai}预览文件内容"
        echo -e "${gl_bufan}17. ${gl_bai}搜索文件  ${gl_bufan}18. ${gl_bai}查找大文件 ${gl_bufan}19. ${gl_bai}创建并编辑文件"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_bufan}通用操作 ${gl_huang}${gl_bai}"
        echo -e "${gl_bufan}21. ${gl_bai}压缩文件  ${gl_bufan}22. ${gl_bai}解压文件   ${gl_bufan}23. ${gl_bai}解压/压缩工具"
        echo -e "${gl_bufan}24. ${gl_bai}批量改名  ${gl_bufan}25. ${gl_bai}安全删除   ${gl_bufan}26. ${gl_bai}下载文件工具"
        echo -e "${gl_bufan}27. ${gl_bai}移动文件  ${gl_bufan}28. ${gl_bai}复制文件   ${gl_bufan}29. ${gl_bai}文件回收站"
        echo -e "${gl_bufan}31. ${gl_bai}搜索内容  ${gl_bufan}32. ${gl_bai}搜索并处理 ${gl_bufan}33. ${gl_bai}实时监控目录大小"
        echo -e "${gl_bufan}34. ${gl_bai}文件去重  ${gl_bufan}35. ${gl_bai}图片转格式 ${gl_bufan}36. ${gl_bai}传送文件至远端"
        echo -e "${gl_bufan}37. ${gl_bai}文件信息  ${gl_bufan}38. ${gl_bai}生成目录树 ${gl_bufan}39. ${gl_bai}常用目录管理"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_huang}0.  ${gl_bai}返回上一级选单           ${gl_hong}00. ${gl_bai}退出脚本"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        read -r -e -p "$(echo -e "${gl_bai}请输入你的选择: ")" Limiting

        case "$Limiting" in
        1)  enter_directory "文件管理器" ;;
        2)  create_directory "文件管理器" || continue ;;
        3)  modify_directory_permissions || continue ;;
        4)  rename_directory ;;
        5)  delete_directories ;;
        6)  go_parent_directory ;;
        7)  search_dir_here ;;
        8)  find_large_directories ;;
        9)  list_directory_sizes ;;
        11) create_new_file ;;
        12) edit_file_with_nano ;;
        13) file_chmod "文件管理器" ;;
        14) rename_file_or_dir ;;
        15) delete_files ;;
        16) cat_view_file_content "文件管理器" ;;
        17) search_file_here ;;
        18) find_large_files ;;
        19) create_file ;;
        21) compress_file_or_directory ;;
        22) extract_archive ;;
        23) compress_tool ;;
        24) batch_rename_files ;;
        25) interactive_delete ;;
        26) download_file ;;
        27) move_file_or_directory ;;
        28) copy_file_or_directory ;;
        29) manage_trash_menu ;;
        31) search_here ;;
        32) manual_file_search_and_process ;;
        33) duwatch ;;
        34) remove_duplicate_files ;;
        35) image_converter_main "文件管理器" ;;
        36) transfer_file_to_remote ;;
        37) check_directory_empty "." "查看文件信息" "true" || continue
            select_and_display_file_info "." 1 4 ;;
        38) show_directory_tree ;;
        39) manage_backup_files_simple "linux_file" ;;
        0) cancel_return "$menu_name"; return ;;
        00 | 000 | 0000) exit_script ;;
        *)  handle_invalid_input ;;
        esac
    done
}

main() {
    local target_dir="${1:-}"
    
    if [[ -n "$target_dir" ]] && [[ -d "$target_dir" ]]; then
        cd "$target_dir" && linux_file "$(pwd)" "文件管理器" "主菜单"
    elif [[ -n "$SCRIPT_WORKDIR" ]] && [[ -d "$SCRIPT_WORKDIR" ]]; then
        cd "$SCRIPT_WORKDIR" && linux_file "$(pwd)" "文件管理器" "主菜单"
    else
        linux_file "$(pwd)" "文件管理器" "主菜单"
    fi
}

is_pve_system() {
    if [ ! -d "/var/lib/vz/template/iso" ]; then
        echo -e ""
        echo -en "${gl_hong}你这不是 ${gl_huang}PVE${gl_hong} 系统!\c"
        exit_script
        exit 0
    fi
    return 0
}

pve_file_menu() {
    while true; do
        is_pve_system || return 1
        clear
        echo -e "${gl_zi}>>> PVE 文件管理${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_bufan}1.  ${gl_bai}镜像文件管理       ${gl_bufan}2.  ${gl_bai}备份文件管理"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_huang}0.  ${gl_bai}返回上一级选单     ${gl_hong}00. ${gl_bai}退出脚本"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        read -r -e -p "请输入你的选择: " choice
        
        case $choice in
        1) linux_file /var/lib/vz/template/iso "PVE 镜像文件管理" "主菜单" ;;
        2) linux_file /var/lib/vz/dump "PVE 备份文件管理" "主菜单" ;;
        0) cancel_return; break ;;
        00 | 000 | 0000) exit_script ;;
        *) handle_invalid_input ;;
        esac
    done
}

pve_file_menu

parse_arguments "$@"
main "$@"

创建本地脚本

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"