From 9b1e435f4f2170ec7657789d7d9a0dbf3b8ee727 Mon Sep 17 00:00:00 2001 From: shenmo Date: Tue, 9 Dec 2025 09:10:29 +0000 Subject: [PATCH] Revert "update src/usr/bin/amber-pm-convert." This reverts commit 61e747ba088d398c4e6401110803146e203f81aa. --- src/usr/bin/amber-pm-convert | 967 +++++++++++++++++------------------ 1 file changed, 483 insertions(+), 484 deletions(-) diff --git a/src/usr/bin/amber-pm-convert b/src/usr/bin/amber-pm-convert index 6f7424f..0bed887 100755 --- a/src/usr/bin/amber-pm-convert +++ b/src/usr/bin/amber-pm-convert @@ -1,41 +1,41 @@ #!/bin/bash # APM软件包转换器 - 将DEB包转换为APM格式 -log.warn()  { echo -e "[\e[33mWARN\e[0m]:  \e[1m$*\e[0m"; } +log.warn() { echo -e "[\e[33mWARN\e[0m]: \e[1m$*\e[0m"; } log.error() { echo -e "[\e[31mERROR\e[0m]: \e[1m$*\e[0m"; } -log.info()  { echo -e "[\e[96mINFO\e[0m]:  \e[1m$*\e[0m"; } +log.info() { echo -e "[\e[96mINFO\e[0m]: \e[1m$*\e[0m"; } log.debug() { echo -e "[\e[32mDEBUG\e[0m]: \e[1m$*\e[0m"; } SCRIPT_NAME=$(basename "$0") if ! command -v dpkg > /dev/null ; then -    log.error "若想使用APM软件包转换器,您需先安装dpkg" -    exit 1 + log.error "若想使用APM软件包转换器,您需先安装dpkg" + exit 1 fi # 显示用法信息 usage() { -    echo "用法: $SCRIPT_NAME [--manual] --base [--base ...] " -    echo "       或者在手动模式下不传入 DEB 文件: $SCRIPT_NAME --manual --base [--base ...]" -    echo "" -    echo "参数说明:" -    echo "  --manual     启用手动模式:融合挂载后打开交互 shell,退出 shell 后脚本继续" -    echo "  --basename   必填参数(非手动模式下),指定基础环境名称,可多次使用" -    echo "  deb文件路径  要转换的DEB文件路径(非手动且非空模式下必填)" -    echo "  --pkgname    可选参数,指定新包的包名(默认使用原DEB包名)" -    echo "  --version    可选参数,指定新包的版本号(默认在原版本后追加'-apm')" -    echo "" -    echo "示例:" -    echo "  $SCRIPT_NAME --base amber-pm-trixie /path/to/package.deb" -    echo "  $SCRIPT_NAME --manual --base amber-pm-trixie   # 只融合挂载并进入手动 shell" -    echo "  $SCRIPT_NAME --manual --base amber-pm-trixie --pkgname newpkg --version 1.2.3 /path/to/package.deb" -    echo "" -    echo "说明: 最下层的base在最后面,从上到下写base" + echo "用法: $SCRIPT_NAME [--manual] --base [--base ...] " + echo " 或者在手动模式下不传入 DEB 文件: $SCRIPT_NAME --manual --base [--base ...]" + echo "" + echo "参数说明:" + echo " --manual 启用手动模式:融合挂载后打开交互 shell,退出 shell 后脚本继续" + echo " --basename 必填参数(非手动模式下),指定基础环境名称,可多次使用" + echo " deb文件路径 要转换的DEB文件路径(非手动且非空模式下必填)" + echo " --pkgname 可选参数,指定新包的包名(默认使用原DEB包名)" + echo " --version 可选参数,指定新包的版本号(默认在原版本后追加'-apm')" + echo "" + echo "示例:" + echo " $SCRIPT_NAME --base amber-pm-trixie /path/to/package.deb" + echo " $SCRIPT_NAME --manual --base amber-pm-trixie # 只融合挂载并进入手动 shell" + echo " $SCRIPT_NAME --manual --base amber-pm-trixie --pkgname newpkg --version 1.2.3 /path/to/package.deb" + echo "" + echo "说明: 最下层的base在最后面,从上到下写base" } # 解析参数 -BASENAMES=()        # 存放实际用于构建 overlay 的 base(可能会被递归添加) -BASENAMES_ORIG=()   # 存放用户原始输入的 base 列表(用于 control 中 Depends 等) +BASENAMES=() # 存放实际用于构建 overlay 的 base(可能会被递归添加) +BASENAMES_ORIG=() # 存放用户原始输入的 base 列表(用于 control 中 Depends 等) DEB_PATH="" PKGNAME="" VERSION="" @@ -43,81 +43,81 @@ MANUAL_MODE=false # 简单参数解析(顺序敏感) while [ $# -gt 0 ]; do -    case "$1" in -        --base) -            if [ -z "$2" ]; then -                log.error "--base 后需要跟名称" -                usage -                exit 1 -            fi -            BASENAMES+=("$2") -            BASENAMES_ORIG+=("$2") -            shift 2 -            ;; -        --pkgname) -            PKGNAME="$2" -            shift 2 -            ;; -        --version) -            VERSION="$2" -            shift 2 -            ;; -        --manual) -            MANUAL_MODE=true -            shift -            ;; -        -*) -            log.error "未知选项: $1" -            usage -            exit 1 -            ;; -        *) -            # 非选项,视为 DEB 路径(只接受第一个非选项作为 DEB) -            if [ -z "$DEB_PATH" ]; then -                DEB_PATH="$1" -                shift -            else -                log.error "未知参数或多余的参数: $1" -                usage -                exit 1 -            fi -            ;; -    esac + case "$1" in + --base) + if [ -z "$2" ]; then + log.error "--base 后需要跟名称" + usage + exit 1 + fi + BASENAMES+=("$2") + BASENAMES_ORIG+=("$2") + shift 2 + ;; + --pkgname) + PKGNAME="$2" + shift 2 + ;; + --version) + VERSION="$2" + shift 2 + ;; + --manual) + MANUAL_MODE=true + shift + ;; + -*) + log.error "未知选项: $1" + usage + exit 1 + ;; + *) + # 非选项,视为 DEB 路径(只接受第一个非选项作为 DEB) + if [ -z "$DEB_PATH" ]; then + DEB_PATH="$1" + shift + else + log.error "未知参数或多余的参数: $1" + usage + exit 1 + fi + ;; + esac done # 基本参数验证: # 如果不是手动模式,则至少需要一个 --base 和一个 deb 文件 if [ "$MANUAL_MODE" = false ]; then -    if [ ${#BASENAMES[@]} -eq 0 ] || [ -z "$DEB_PATH" ]; then -        log.error "错误:非手动模式下至少需要一个 --base 参数 且 必须提供 DEB 文件路径" -        usage -        exit 1 -    fi + if [ ${#BASENAMES[@]} -eq 0 ] || [ -z "$DEB_PATH" ]; then + log.error "错误:非手动模式下至少需要一个 --base 参数 且 必须提供 DEB 文件路径" + usage + exit 1 + fi else -    # 手动模式下允许没有 DEB_FILE,但仍然要有至少一个 base -    if [ ${#BASENAMES[@]} -eq 0 ]; then -        log.error "错误:手动模式下仍需提供至少一个 --base 参数" -        usage -        exit 1 -    fi + # 手动模式下允许没有 DEB_FILE,但仍然要有至少一个 base + if [ ${#BASENAMES[@]} -eq 0 ]; then + log.error "错误:手动模式下仍需提供至少一个 --base 参数" + usage + exit 1 + fi fi # 如果传入了 DEB_PATH,检查文件是否存在 if [ -n "$DEB_PATH" ] && [ ! -f "$DEB_PATH" ]; then -    log.error "错误:DEB文件不存在: $DEB_PATH" -    exit 1 + log.error "错误:DEB文件不存在: $DEB_PATH" + exit 1 fi log.info "开始转换(手动模式: $MANUAL_MODE)" log.info "基础环境数量: ${#BASENAMES_ORIG[@]}" for i in "${!BASENAMES_ORIG[@]}"; do -    log.info "  原始基础环境 $((i+1)): ${BASENAMES_ORIG[$i]}" + log.info " 原始基础环境 $((i+1)): ${BASENAMES_ORIG[$i]}" done if [ -n "$DEB_PATH" ]; then -    log.info "目标 DEB: $DEB_PATH" + log.info "目标 DEB: $DEB_PATH" else -    log.info "未提供 DEB 文件,处于纯手动模式(手动修改/安装/打包)" + log.info "未提供 DEB 文件,处于纯手动模式(手动修改/安装/打包)" fi # 1. 创建临时工作目录 @@ -128,20 +128,20 @@ export CRAFT_DIR # 检查是否已挂载,避免重复挂载 cleanup_mount() { -    if mountpoint -q "$CRAFT_DIR/mergedir"; then -        log.info "解除挂载: $CRAFT_DIR/mergedir" -        sudo umount "$CRAFT_DIR/mergedir" || true -    fi + if mountpoint -q "$CRAFT_DIR/mergedir"; then + log.info "解除挂载: $CRAFT_DIR/mergedir" + sudo umount "$CRAFT_DIR/mergedir" || true + fi } # 清理函数 cleanup() { -    log.info "开始清理..." -    cleanup_mount -    if [ -d "$CRAFT_DIR" ]; then -        log.info "删除临时目录: $CRAFT_DIR" -        sudo rm -rf "$CRAFT_DIR" -    fi + log.info "开始清理..." + cleanup_mount + if [ -d "$CRAFT_DIR" ]; then + log.info "删除临时目录: $CRAFT_DIR" + sudo rm -rf "$CRAFT_DIR" + fi } # 设置退出时清理 @@ -149,52 +149,52 @@ trap cleanup EXIT # 递归获取info文件中的依赖 (会把新依赖追加到 BASENAMES 数组中) get_recursive_basenames() { -    local basename="$1" -    # 注意:根据之前脚本结构,info 存放在 /var/lib/apm/apm/files/ace-env/var/lib/apm//info -    local base_dir="/var/lib/apm/apm/files/ace-env/var/lib/apm/$basename" -    local info_file="$base_dir/info" + local basename="$1" + # 注意:根据之前脚本结构,info 存放在 /var/lib/apm/apm/files/ace-env/var/lib/apm//info + local base_dir="/var/lib/apm/apm/files/ace-env/var/lib/apm/$basename" + local info_file="$base_dir/info" -    if [ -f "$info_file" ]; then -        log.info "读取info文件: $info_file" -        while IFS= read -r base; do -            [[ -z "$base" ]] && continue -            # 如果依赖的 base 没有被记录过,则递归添加 -            local found=false -            for existing in "${BASENAMES[@]}"; do -                if [ "$existing" = "$base" ]; then -                    found=true -                    break -                fi -            done -            if [ "$found" = false ]; then -                BASENAMES+=("$base") -                get_recursive_basenames "$base" -            fi -        done < "$info_file" -    else -        log.info "未找到info文件,跳过: $info_file" -    fi + if [ -f "$info_file" ]; then + log.info "读取info文件: $info_file" + while IFS= read -r base; do + [[ -z "$base" ]] && continue + # 如果依赖的 base 没有被记录过,则递归添加 + local found=false + for existing in "${BASENAMES[@]}"; do + if [ "$existing" = "$base" ]; then + found=true + break + fi + done + if [ "$found" = false ]; then + BASENAMES+=("$base") + get_recursive_basenames "$base" + fi + done < "$info_file" + else + log.info "未找到info文件,跳过: $info_file" + fi } # 递归获取所有基础环境(从用户输入的 base 开始) for BASE in "${BASENAMES[@]}"; do -    get_recursive_basenames "$BASE" + get_recursive_basenames "$BASE" done # 如果用户传了 DEB,则读取原包信息(否则跳过) if [ -n "$DEB_PATH" ]; then -    log.info "检查原DEB包信息..." -    ORIG_PKGNAME=$(dpkg -f "$DEB_PATH" Package 2>/dev/null || echo "") -    ORIG_VERSION=$(dpkg -f "$DEB_PATH" Version 2>/dev/null || echo "") -    ORIG_ARCH=$(dpkg -f "$DEB_PATH" Architecture 2>/dev/null || echo "") + log.info "检查原DEB包信息..." + ORIG_PKGNAME=$(dpkg -f "$DEB_PATH" Package 2>/dev/null || echo "") + ORIG_VERSION=$(dpkg -f "$DEB_PATH" Version 2>/dev/null || echo "") + ORIG_ARCH=$(dpkg -f "$DEB_PATH" Architecture 2>/dev/null || echo "") -    log.info "原包名: ${ORIG_PKGNAME:-未知}" -    log.info "原版本: ${ORIG_VERSION:-未知}" -    log.info "原架构: ${ORIG_ARCH:-unknown}" + log.info "原包名: ${ORIG_PKGNAME:-未知}" + log.info "原版本: ${ORIG_VERSION:-未知}" + log.info "原架构: ${ORIG_ARCH:-unknown}" else -    ORIG_PKGNAME="" -    ORIG_VERSION="" -    ORIG_ARCH="$(dpkg --print-architecture 2>/dev/null || echo "unknown")" + ORIG_PKGNAME="" + ORIG_VERSION="" + ORIG_ARCH="$(dpkg --print-architecture 2>/dev/null || echo "unknown")" fi # 设置新包名和版本(若手动模式且未指定,则稍后询问) @@ -210,21 +210,21 @@ log.info "构建 overlay lowerdir 路径..." LOWERDIRS=() for BASENAME in "${BASENAMES[@]}"; do -    ACE_ENV_PATH="/var/lib/apm/apm/files/ace-env/var/lib/apm/${BASENAME}/files/ace-env" -    CORE_PATH="/var/lib/apm/apm/files/ace-env/var/lib/apm/${BASENAME}/files/core" + ACE_ENV_PATH="/var/lib/apm/apm/files/ace-env/var/lib/apm/${BASENAME}/files/ace-env" + CORE_PATH="/var/lib/apm/apm/files/ace-env/var/lib/apm/${BASENAME}/files/core" -    if [ -d "$ACE_ENV_PATH" ]; then -        log.info "使用 ace-env 路径: $ACE_ENV_PATH" -        LOWERDIRS+=("$ACE_ENV_PATH") -    elif [ -d "$CORE_PATH" ]; then -        log.info "使用 core 路径: $CORE_PATH" -        LOWERDIRS+=("$CORE_PATH") -    else -        log.error "错误:基础环境路径不存在: $BASENAME" -        log.error "  检查的路径: $ACE_ENV_PATH" -        log.error "  检查的路径: $CORE_PATH" -        exit 1 -    fi + if [ -d "$ACE_ENV_PATH" ]; then + log.info "使用 ace-env 路径: $ACE_ENV_PATH" + LOWERDIRS+=("$ACE_ENV_PATH") + elif [ -d "$CORE_PATH" ]; then + log.info "使用 core 路径: $CORE_PATH" + LOWERDIRS+=("$CORE_PATH") + else + log.error "错误:基础环境路径不存在: $BASENAME" + log.error " 检查的路径: $ACE_ENV_PATH" + log.error " 检查的路径: $CORE_PATH" + exit 1 + fi done # 将 lowerdirs 数组用冒号连接 @@ -234,12 +234,12 @@ log.debug "最终 lowerdir: $LOWERDIR" # 3. 进行融合挂载 log.info "正在进行融合挂载..." sudo mount -t overlay overlay \ -    -o "lowerdir=$LOWERDIR,upperdir=$CRAFT_DIR/core/,workdir=$CRAFT_DIR/work/" \ -    "$CRAFT_DIR/mergedir" + -o "lowerdir=$LOWERDIR,upperdir=$CRAFT_DIR/core/,workdir=$CRAFT_DIR/work/" \ + "$CRAFT_DIR/mergedir" if ! mountpoint -q "$CRAFT_DIR/mergedir"; then -    log.error "错误:融合挂载失败" -    exit 1 + log.error "错误:融合挂载失败" + exit 1 fi log.info "挂载完成: $CRAFT_DIR/mergedir" @@ -250,351 +250,350 @@ log.debug "已导出 chrootEnvPath=$chrootEnvPath" # 如果在手动模式下,立即打开交互 shell 并在退出后继续脚本 if [ "$MANUAL_MODE" = true ]; then -    log.info "进入手动模式:将在融合挂载环境中打开交互 shell(使用 ace-run-pkg)。" -    log.info "在 shell 中,您可以手动修改、测试安装或进行其他操作。退出 shell 后脚本将继续。" -    # 启动交互 shell,保留环境变量(使用 sudo -E) -    sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg bash --login || { -        log.warn "ace-run-pkg shell 退出或出现错误,继续脚本..." -    } -    log.info "用户已退出手动 shell,脚本将继续。" -    # 如果没有 DEB,询问是否要进行后续打包(允许返回 shell) -    if [ -z "$DEB_PATH" ]; then -        while true; do -            echo "" -            read -r -p "未提供 DEB 文件。是否现在进行新 APM 包的自动打包? (y = 打包, r = 返回 shell, n = 跳过打包) [y/r/n]: " yn -            case "$yn" in -                y|Y) -                    # 如果缺少包名或版本,交互询问 -                    if [ -z "$NEW_PKGNAME" ]; then -                        read -r -p "请输入要创建的包名 (Package): " NEW_PKGNAME -                    fi -                    if [ -z "$NEW_VERSION" ] || [[ "$NEW_VERSION" == "-apm" ]]; then -                        read -r -p "请输入要创建的版本 (Version): " NEW_VERSION -                    fi -                    break -                    ;; -                r|R) -                    log.info "返回交互 shell(使用 ace-run-pkg)。退出 shell 后再次询问。" -                    sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg bash --login || true -                    ;; -                n|N) -                    log.info "跳过自动打包。脚本结束。" -                    exit 0 -                    ;; -                *) -                    echo "请输入 y, r, 或 n。" -                    ;; -            esac -        done -    fi + log.info "进入手动模式:将在融合挂载环境中打开交互 shell(使用 ace-run-pkg)。" + log.info "在 shell 中,您可以手动修改、测试安装或进行其他操作。退出 shell 后脚本将继续。" + # 启动交互 shell,保留环境变量(使用 sudo -E) + sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg bash --login || { + log.warn "ace-run-pkg shell 退出或出现错误,继续脚本..." + } + log.info "用户已退出手动 shell,脚本将继续。" + # 如果没有 DEB,询问是否要进行后续打包(允许返回 shell) + if [ -z "$DEB_PATH" ]; then + while true; do + echo "" + read -r -p "未提供 DEB 文件。是否现在进行新 APM 包的自动打包? (y = 打包, r = 返回 shell, n = 跳过打包) [y/r/n]: " yn + case "$yn" in + y|Y) + # 如果缺少包名或版本,交互询问 + if [ -z "$NEW_PKGNAME" ]; then + read -r -p "请输入要创建的包名 (Package): " NEW_PKGNAME + fi + if [ -z "$NEW_VERSION" ] || [[ "$NEW_VERSION" == "-apm" ]]; then + read -r -p "请输入要创建的版本 (Version): " NEW_VERSION + fi + break + ;; + r|R) + log.info "返回交互 shell(使用 ace-run-pkg)。退出 shell 后再次询问。" + sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg bash --login || true + ;; + n|N) + log.info "跳过自动打包。脚本结束。" + exit 0 + ;; + *) + echo "请输入 y, r, 或 n。" + ;; + esac + done + fi fi # 到这里:非手动模式或手动模式退出后继续(如果是非手动并且有 DEB,继续原本流程) # 函数:查找并处理符号链接,返回实际文件路径 resolve_symlink() { -    local file="$1" -    local target_dir="$2" -     -    if [ -L "$file" ]; then -        # 获取符号链接目标 -        local target=$(readlink "$file") -         -        # 如果目标是绝对路径,则在目标目录中查找 -        if [[ "$target" == /* ]]; then -            local resolved_path="$target_dir${target}" -            if [ -f "$resolved_path" ]; then -                echo "$resolved_path" -                return 0 -            fi -        else -            # 相对路径,在符号链接所在目录解析 -            local link_dir=$(dirname "$file") -            local resolved_path="$link_dir/$target" -            if [ -f "$resolved_path" ]; then -                echo "$resolved_path" -                return 0 -            fi -        fi -    fi -     -    # 如果不是符号链接或解析失败,返回原文件 -    echo "$file" + local file="$1" + local target_dir="$2" + + if [ -L "$file" ]; then + # 获取符号链接目标 + local target=$(readlink "$file") + + # 如果目标是绝对路径,则在目标目录中查找 + if [[ "$target" == /* ]]; then + local resolved_path="$target_dir${target}" + if [ -f "$resolved_path" ]; then + echo "$resolved_path" + return 0 + fi + else + # 相对路径,在符号链接所在目录解析 + local link_dir=$(dirname "$file") + local resolved_path="$link_dir/$target" + if [ -f "$resolved_path" ]; then + echo "$resolved_path" + return 0 + fi + fi + fi + + # 如果不是符号链接或解析失败,返回原文件 + echo "$file" } # 函数:交互式选择文件复制到entries目录(用于手动模式无DEB情况) interactive_copy_entries() { -    local core_dir="$CRAFT_DIR/core" -    local entries_dir="$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/entries" -     -    log.info "开始交互式选择文件复制到 entries 目录..." -    mkdir -p "$entries_dir/applications" "$entries_dir/icons" -     -    # 查找桌面文件 -    local desktop_files=() -    while IFS= read -r -d '' file; do -        [[ -f "$file" ]] && desktop_files+=("$file") -    done < <(find "$core_dir/usr/share" -name "*.desktop" -print0 2>/dev/null || true) -     -    # 查找图标文件 -    local icon_files=() -    while IFS= read -r -d '' file; do -        [[ -f "$file" ]] && icon_files+=("$file") -    done < <(find "$core_dir/usr/share" \( -name "*.png" -o -name "*.svg" -o -name "*.xpm" \) -print0 2>/dev/null || true) -     -    # 处理桌面文件 -    if [ ${#desktop_files[@]} -gt 0 ]; then -        log.info "找到 ${#desktop_files[@]} 个桌面文件:" -        for i in "${!desktop_files[@]}"; do -            local file="${desktop_files[$i]}" -            local relative_path="${file#$core_dir}" # 获取相对于 core_dir 的路径 -            echo "  $((i+1)). $relative_path" # 打印相对路径 -             -            # 检查是否是符号链接 -            if [ -L "$file" ]; then -                local target=$(readlink "$file") -                echo "      → 符号链接指向: $target" -                # 解析符号链接获取实际文件 -                local resolved_file=$(resolve_symlink "$file" "$core_dir") -                if [ "$resolved_file" != "$file" ] && [ -f "$resolved_file" ]; then -                    local resolved_relative_path="${resolved_file#$core_dir}" -                    echo "      → 解析为: $resolved_relative_path" -                    desktop_files[$i]="$resolved_file" -                fi -            fi -        done -         -        echo "" -        read -r -p "请选择要复制的桌面文件编号(多个用逗号分隔,all=全部,none=跳过): " desktop_choice -         -        if [[ "$desktop_choice" =~ ^[Aa][Ll][Ll]$ ]]; then -            # 复制所有桌面文件到 entries/applications -            for file in "${desktop_files[@]}"; do -                local filename=$(basename "$file") -                local dest_path="$entries_dir/applications/$filename" -                cp -v "$file" "$dest_path" -                 -                # 处理桌面文件内容 -                process_desktop_file "$dest_path" "$NEW_PKGNAME" -            done -        elif [[ ! "$desktop_choice" =~ ^[Nn][Oo][Nn][Ee]$ ]] && [ -n "$desktop_choice" ]; then -            # 处理选择的文件 -            IFS=',' read -ra choices <<< "$desktop_choice" -            for choice in "${choices[@]}"; do -                choice=$(echo "$choice" | tr -d ' ') -                if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le ${#desktop_files[@]} ]; then -                    local idx=$((choice-1)) -                    local file="${desktop_files[$idx]}" -                    local filename=$(basename "$file") -                    local dest_path="$entries_dir/applications/$filename" -                    cp -v "$file" "$dest_path" -                     -                    # 处理桌面文件内容 -                    process_desktop_file "$dest_path" "$NEW_PKGNAME" -                else -                    log.warn "无效的选择: $choice" -                fi -            done -        else -            log.info "跳过桌面文件复制" -        fi -    else -        log.info "未找到桌面文件" -    fi -     -    # 处理图标文件 -    if [ ${#icon_files[@]} -gt 0 ]; then -        log.info "找到 ${#icon_files[@]} 个图标文件:" -        for i in "${!icon_files[@]}"; do -            local file="${icon_files[$i]}" -            local relative_path="${file#$core_dir}"  # <-- 修改:获取相对于 core_dir 的路径 -            echo "  $((i+1)). $relative_path"          # <-- 修改:打印相对路径 -             -            # 检查是否是符号链接 -            if [ -L "$file" ]; then -                local target=$(readlink "$file") -                echo "      → 符号链接指向: $target" -                # 解析符号链接获取实际文件 -                local resolved_file=$(resolve_symlink "$file" "$core_dir") -                if [ "$resolved_file" != "$file" ] && [ -f "$resolved_file" ]; then -                    local resolved_relative_path="${resolved_file#$core_dir}" # <-- 修改:计算解析后的相对路径 -                    echo "      → 解析为: $resolved_relative_path"              # <-- 修改:打印解析后的相对路径 -                    icon_files[$i]="$resolved_file" -                fi -            fi -        done -         -        echo "" -        read -r -p "请选择要复制的图标文件编号(多个用逗号分隔,all=全部,none=跳过): " icon_choice -         -        if [[ "$icon_choice" =~ ^[Aa][Ll][Ll]$ ]]; then -            # 复制所有图标文件到 entries/icons -            for file in "${icon_files[@]}"; do -                local filename=$(basename "$file") -                local dest_path="$entries_dir/icons/$filename" -                cp -v "$file" "$dest_path" -            done -        elif [[ ! "$icon_choice" =~ ^[Nn][Oo][Nn][Ee]$ ]] && [ -n "$icon_choice" ]; then -            # 处理选择的文件 -            IFS=',' read -ra choices <<< "$icon_choice" -            for choice in "${choices[@]}"; do -                choice=$(echo "$choice" | tr -d ' ') -                if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le ${#icon_files[@]} ]; then -                    local idx=$((choice-1)) -                    local file="${icon_files[$idx]}" -                    local filename=$(basename "$file") -                    local dest_path="$entries_dir/icons/$filename" -                    cp -v "$file" "$dest_path" -                else -                    log.warn "无效的选择: $choice" -                fi -            done -        else -            log.info "跳过图标文件复制" -        fi -    else -        log.info "未找到图标文件" -    fi + local core_dir="$CRAFT_DIR/core" + local entries_dir="$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/entries" + + log.info "开始交互式选择文件复制到 entries 目录..." + mkdir -p "$entries_dir/applications" "$entries_dir/icons" + + # 查找桌面文件 + local desktop_files=() + while IFS= read -r -d '' file; do + [[ -f "$file" ]] && desktop_files+=("$file") + done < <(find "$core_dir/usr/share" -name "*.desktop" -print0 2>/dev/null || true) + + # 查找图标文件 + local icon_files=() + while IFS= read -r -d '' file; do + [[ -f "$file" ]] && icon_files+=("$file") + done < <(find "$core_dir/usr/share" \( -name "*.png" -o -name "*.svg" -o -name "*.xpm" \) -print0 2>/dev/null || true) + + # 处理桌面文件 + if [ ${#desktop_files[@]} -gt 0 ]; then + log.info "找到 ${#desktop_files[@]} 个桌面文件:" + for i in "${!desktop_files[@]}"; do + local file="${desktop_files[$i]}" + local filename=$(basename "$file") + echo " $((i+1)). $filename" + + # 检查是否是符号链接 + if [ -L "$file" ]; then + local target=$(readlink "$file") + echo " → 符号链接指向: $target" + # 解析符号链接获取实际文件 + local resolved_file=$(resolve_symlink "$file" "$core_dir") + if [ "$resolved_file" != "$file" ] && [ -f "$resolved_file" ]; then + echo " → 解析为: $(basename "$resolved_file")" + desktop_files[$i]="$resolved_file" + fi + fi + done + + echo "" + read -r -p "请选择要复制的桌面文件编号(多个用逗号分隔,all=全部,none=跳过): " desktop_choice + + if [[ "$desktop_choice" =~ ^[Aa][Ll][Ll]$ ]]; then + # 复制所有桌面文件到 entries/applications + for file in "${desktop_files[@]}"; do + local filename=$(basename "$file") + local dest_path="$entries_dir/applications/$filename" + cp -v "$file" "$dest_path" + + # 处理桌面文件内容 + process_desktop_file "$dest_path" "$NEW_PKGNAME" + done + elif [[ ! "$desktop_choice" =~ ^[Nn][Oo][Nn][Ee]$ ]] && [ -n "$desktop_choice" ]; then + # 处理选择的文件 + IFS=',' read -ra choices <<< "$desktop_choice" + for choice in "${choices[@]}"; do + choice=$(echo "$choice" | tr -d ' ') + if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le ${#desktop_files[@]} ]; then + local idx=$((choice-1)) + local file="${desktop_files[$idx]}" + local filename=$(basename "$file") + local dest_path="$entries_dir/applications/$filename" + cp -v "$file" "$dest_path" + + # 处理桌面文件内容 + process_desktop_file "$dest_path" "$NEW_PKGNAME" + else + log.warn "无效的选择: $choice" + fi + done + else + log.info "跳过桌面文件复制" + fi + else + log.info "未找到桌面文件" + fi + + # 处理图标文件 + if [ ${#icon_files[@]} -gt 0 ]; then + log.info "找到 ${#icon_files[@]} 个图标文件:" + for i in "${!icon_files[@]}"; do + local file="${icon_files[$i]}" + local filename=$(basename "$file") + echo " $((i+1)). $filename" + + # 检查是否是符号链接 + if [ -L "$file" ]; then + local target=$(readlink "$file") + echo " → 符号链接指向: $target" + # 解析符号链接获取实际文件 + local resolved_file=$(resolve_symlink "$file" "$core_dir") + if [ "$resolved_file" != "$file" ] && [ -f "$resolved_file" ]; then + echo " → 解析为: $(basename "$resolved_file")" + icon_files[$i]="$resolved_file" + fi + fi + done + + echo "" + read -r -p "请选择要复制的图标文件编号(多个用逗号分隔,all=全部,none=跳过): " icon_choice + + if [[ "$icon_choice" =~ ^[Aa][Ll][Ll]$ ]]; then + # 复制所有图标文件到 entries/icons + for file in "${icon_files[@]}"; do + local filename=$(basename "$file") + local dest_path="$entries_dir/icons/$filename" + cp -v "$file" "$dest_path" + done + elif [[ ! "$icon_choice" =~ ^[Nn][Oo][Nn][Ee]$ ]] && [ -n "$icon_choice" ]; then + # 处理选择的文件 + IFS=',' read -ra choices <<< "$icon_choice" + for choice in "${choices[@]}"; do + choice=$(echo "$choice" | tr -d ' ') + if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le ${#icon_files[@]} ]; then + local idx=$((choice-1)) + local file="${icon_files[$idx]}" + local filename=$(basename "$file") + local dest_path="$entries_dir/icons/$filename" + cp -v "$file" "$dest_path" + else + log.warn "无效的选择: $choice" + fi + done + else + log.info "跳过图标文件复制" + fi + else + log.info "未找到图标文件" + fi } +# 函数:处理桌面文件内容 # 函数:处理桌面文件内容(安全版本,避免重复处理) process_desktop_file() { -    local desktop_file="$1" -    local pkgname="$2" -    # 新增:精确路径检查 -    local apps_path1="/usr/share/applications" -    local apps_path2="/opt/apps/${ORIG_PKGNAME}/entries/applications" -    local apps_path3="/usr/local/share/applications" -     -    if [[ ! "$desktop_file" =~ ^.*${apps_path1}/.*\.desktop$ ]] &&  -       [[ ! "$desktop_file" =~ ^.*${apps_path2}/.*\.desktop$ ]] && -       [[ ! "$desktop_file" =~ ^.*${apps_path3}/.*\.desktop$ ]]; then -        log.debug "跳过非应用程序 desktop 文件: $desktop_file" -        return 0 -    fi -     -    log.info "处理桌面文件: $desktop_file" -     -    # 检查文件是否已经处理过(避免重复添加 apm run) -    if grep -q "^Exec=apm run $pkgname " "$desktop_file"; then -        log.info "桌面文件已经处理过,跳过: $desktop_file" -        return 0 -    fi -     -    # 检查是否有其他包的 apm run 前缀(清理旧的) -    if grep -q "^Exec=apm run [^ ]* " "$desktop_file"; then -        log.info "发现旧的 apm run 前缀,清理后重新添加" -        # 移除所有 apm run 前缀 -        sed -i "s|^Exec=apm run [^ ]* ||" "$desktop_file" -    fi -     -    # 尝试用 busybox dos2unix(若不存在则跳过转换) -    if command -v busybox >/dev/null 2>&1; then -        busybox dos2unix "$desktop_file" 2>/dev/null || true -    else -        dos2unix "$desktop_file" 2>/dev/null || true -    fi -     -    # 处理 Exec 行:在原有命令前追加 apm run $pkgname -    if grep -q '^Exec=' "$desktop_file"; then -        sed -i "s|^Exec=\(.*\)$|Exec=apm run $pkgname \1|" "$desktop_file" -    fi -     -    # 删除 TryExec 行 -    if grep -q '^TryExec=' "$desktop_file"; then -        sed -i '/^TryExec=/d' "$desktop_file" -        log.info "已删除 TryExec 行" -    fi -     -    # 处理 Icon 路径(若以 / 开头) -    if grep -q '^Icon=/' "$desktop_file"; then -        sed -i "s|^Icon=/|Icon=/var/lib/apm/apm/files/ace-env/var/lib/apm/$pkgname/files/core/|" "$desktop_file" -    fi -     -    # 添加 X-APM-APPID(如果不存在) -    if ! grep -q "X-APM-APPID" "$desktop_file"; then -        echo "" >> "$desktop_file" -        echo "X-APM-APPID=$pkgname" >> "$desktop_file" -    fi -     -    # 检查修改结果并打印调试 -    if grep -q "apm run $pkgname" "$desktop_file"; then -        log.info "桌面文件修改成功: $desktop_file" -    else -        log.warn "桌面文件可能未正确修改: $desktop_file" -    fi + local desktop_file="$1" + local pkgname="$2" + # 新增:精确路径检查 + local apps_path1="/usr/share/applications" + local apps_path2="/opt/apps/${ORIG_PKGNAME}/entries/applications" + local apps_path3="/usr/local/share/applications" + + if [[ ! "$desktop_file" =~ ^.*${apps_path1}/.*\.desktop$ ]] && + [[ ! "$desktop_file" =~ ^.*${apps_path2}/.*\.desktop$ ]] && + [[ ! "$desktop_file" =~ ^.*${apps_path3}/.*\.desktop$ ]]; then + log.debug "跳过非应用程序 desktop 文件: $desktop_file" + return 0 + fi + + log.info "处理桌面文件: $desktop_file" + + # 检查文件是否已经处理过(避免重复添加 apm run) + if grep -q "^Exec=apm run $pkgname " "$desktop_file"; then + log.info "桌面文件已经处理过,跳过: $desktop_file" + return 0 + fi + + # 检查是否有其他包的 apm run 前缀(清理旧的) + if grep -q "^Exec=apm run [^ ]* " "$desktop_file"; then + log.info "发现旧的 apm run 前缀,清理后重新添加" + # 移除所有 apm run 前缀 + sed -i "s|^Exec=apm run [^ ]* ||" "$desktop_file" + fi + + # 尝试用 busybox dos2unix(若不存在则跳过转换) + if command -v busybox >/dev/null 2>&1; then + busybox dos2unix "$desktop_file" 2>/dev/null || true + else + dos2unix "$desktop_file" 2>/dev/null || true + fi + + # 处理 Exec 行:在原有命令前追加 apm run $pkgname + if grep -q '^Exec=' "$desktop_file"; then + sed -i "s|^Exec=\(.*\)$|Exec=apm run $pkgname \1|" "$desktop_file" + fi + + # 删除 TryExec 行 + if grep -q '^TryExec=' "$desktop_file"; then + sed -i '/^TryExec=/d' "$desktop_file" + log.info "已删除 TryExec 行" + fi + + # 处理 Icon 路径(若以 / 开头) + if grep -q '^Icon=/' "$desktop_file"; then + sed -i "s|^Icon=/|Icon=/var/lib/apm/apm/files/ace-env/var/lib/apm/$pkgname/files/core/|" "$desktop_file" + fi + + # 添加 X-APM-APPID(如果不存在) + if ! grep -q "X-APM-APPID" "$desktop_file"; then + echo "" >> "$desktop_file" + echo "X-APM-APPID=$pkgname" >> "$desktop_file" + fi + + # 检查修改结果并打印调试 + if grep -q "apm run $pkgname" "$desktop_file"; then + log.info "桌面文件修改成功: $desktop_file" + else + log.warn "桌面文件可能未正确修改: $desktop_file" + fi } # 4. 如果有 DEB 文件,进行自动化的检查、解包与修改 if [ -n "$DEB_PATH" ]; then -    # 在融合环境中更新包列表并做 dry-run 检查(如果 ace-run-pkg aptss 可用) -    log.info "在融合环境中测试安装 DEB 包(dry-run)..." -    sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg aptss update || log.warn "aptss update 返回非零状态,继续但请注意" -    if ! sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg aptss install "$DEB_PATH" --dry-run ; then -        log.error "错误:安装前检查失败,DEB包可能无法在基础环境中安装" -        log.error "请检查依赖关系或基础环境是否兼容" -        exit 1 -    fi -    log.info "安装前检查通过,准备进行提取与修改..." -    sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg mkdir -p /var/cache/apt/archives/partial + # 在融合环境中更新包列表并做 dry-run 检查(如果 ace-run-pkg aptss 可用) + log.info "在融合环境中测试安装 DEB 包(dry-run)..." + sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg aptss update || log.warn "aptss update 返回非零状态,继续但请注意" + if ! sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg aptss install "$DEB_PATH" --dry-run ; then + log.error "错误:安装前检查失败,DEB包可能无法在基础环境中安装" + log.error "请检查依赖关系或基础环境是否兼容" + exit 1 + fi + log.info "安装前检查通过,准备进行提取与修改..." + sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg mkdir -p /var/cache/apt/archives/partial -    # 提取 DEB 包内容并准备修改 -    log.info "提取并修改原DEB包..." -    EXTRACT_DIR="$CRAFT_DIR/extract" -    MODIFIED_DEB_DIR="$CRAFT_DIR/modified_deb" -    mkdir -p "$EXTRACT_DIR" -    mkdir -p "$MODIFIED_DEB_DIR/DEBIAN" + # 提取 DEB 包内容并准备修改 + log.info "提取并修改原DEB包..." + EXTRACT_DIR="$CRAFT_DIR/extract" + MODIFIED_DEB_DIR="$CRAFT_DIR/modified_deb" + mkdir -p "$EXTRACT_DIR" + mkdir -p "$MODIFIED_DEB_DIR/DEBIAN" -    dpkg -x "$DEB_PATH" "$EXTRACT_DIR" -    dpkg -e "$DEB_PATH" "$MODIFIED_DEB_DIR/DEBIAN" + dpkg -x "$DEB_PATH" "$EXTRACT_DIR" + dpkg -e "$DEB_PATH" "$MODIFIED_DEB_DIR/DEBIAN" -    # 处理 .desktop 文件 -    DESKTOP_MODIFIED=false -    while IFS= read -r desktop_file; do -        [ -z "$desktop_file" ] && continue -        process_desktop_file "$desktop_file" "${NEW_PKGNAME:-$ORIG_PKGNAME}" -        DESKTOP_MODIFIED=true -    done < <(find "$EXTRACT_DIR" -name "*.desktop" -print) + # 处理 .desktop 文件 + DESKTOP_MODIFIED=false + while IFS= read -r desktop_file; do + [ -z "$desktop_file" ] && continue + process_desktop_file "$desktop_file" "${NEW_PKGNAME:-$ORIG_PKGNAME}" + DESKTOP_MODIFIED=true + done < <(find "$EXTRACT_DIR" -name "*.desktop" -print) -    if [ "$DESKTOP_MODIFIED" = false ]; then -        log.info "未找到需要修改的 .desktop 文件" -    fi + if [ "$DESKTOP_MODIFIED" = false ]; then + log.info "未找到需要修改的 .desktop 文件" + fi -    # 复制修改后的文件结构到打包目录并重新打包 modified deb(供本地测试/安装使用) -    MODIFIED_DEB_PATH="$CRAFT_DIR/modified_${ORIG_PKGNAME:-package}.deb" -    log.info "重新打包修改后的 DEB: $MODIFIED_DEB_PATH" -    mkdir -p "$MODIFIED_DEB_DIR/data" -    cp -r "$EXTRACT_DIR"/* "$MODIFIED_DEB_DIR/" 2>/dev/null || true + # 复制修改后的文件结构到打包目录并重新打包 modified deb(供本地测试/安装使用) + MODIFIED_DEB_PATH="$CRAFT_DIR/modified_${ORIG_PKGNAME:-package}.deb" + log.info "重新打包修改后的 DEB: $MODIFIED_DEB_PATH" + mkdir -p "$MODIFIED_DEB_DIR/data" + cp -r "$EXTRACT_DIR"/* "$MODIFIED_DEB_DIR/" 2>/dev/null || true -    (cd "$MODIFIED_DEB_DIR" && fakeroot dpkg-deb --build -Z none . "$MODIFIED_DEB_PATH") || { -        log.error "错误:重新打包 DEB 失败" -        exit 1 -    } + (cd "$MODIFIED_DEB_DIR" && fakeroot dpkg-deb --build -Z none . "$MODIFIED_DEB_PATH") || { + log.error "错误:重新打包 DEB 失败" + exit 1 + } -    if [ ! -f "$MODIFIED_DEB_PATH" ]; then -        log.error "错误:重新打包后的 DEB 未生成: $MODIFIED_DEB_PATH" -        exit 1 -    fi -    log.info "修改后的 DEB 包已生成: $MODIFIED_DEB_PATH" + if [ ! -f "$MODIFIED_DEB_PATH" ]; then + log.error "错误:重新打包后的 DEB 未生成: $MODIFIED_DEB_PATH" + exit 1 + fi + log.info "修改后的 DEB 包已生成: $MODIFIED_DEB_PATH" -    # 可选:在融合环境中实际安装修改后的包(默认使用 ssaudit 命令) -    if ! sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg ssaudit "$MODIFIED_DEB_PATH" --native --no-create-desktop-entry ; then -        log.error "错误:修改后的 DEB 包安装失败(ssaudit)" -        exit 1 -    fi -    log.info "修改后的 DEB 包安装完成(ssaudit)" + # 可选:在融合环境中实际安装修改后的包(默认使用 ssaudit 命令) + if ! sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg ssaudit "$MODIFIED_DEB_PATH" --native --no-create-desktop-entry ; then + log.error "错误:修改后的 DEB 包安装失败(ssaudit)" + exit 1 + fi + log.info "修改后的 DEB 包安装完成(ssaudit)" fi -    # 清理 apt 缓存 -    sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg aptss clean || true -    sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg rm -vfr /var/lib/apt/lists || true -    sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg rm -vfr /var/lib/aptss/lists || true -    sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg rm -vfr /var/cache/apt/* || true + # 清理 apt 缓存 + sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg aptss clean || true + sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg rm -vfr /var/lib/apt/lists || true + sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg rm -vfr /var/lib/aptss/lists || true + sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg rm -vfr /var/cache/apt/* || true # 5. 创建新的 APM 包结构 log.info "创建新的APM包结构..." @@ -606,15 +605,15 @@ mkdir -p "$PKG_BUILD_DIR/var/lib/apm/$NEW_PKGNAME"/{entries,files} 2>/dev/null | log.info "创建 info 文件(包含原始输入的基础环境)..." : > "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/info" 2>/dev/null || true for BASENAME in "${BASENAMES_ORIG[@]}"; do -    echo "$BASENAME" >> "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/info" -    log.info "  写入: $BASENAME" + echo "$BASENAME" >> "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/info" + log.info " 写入: $BASENAME" done log.info "创建 info_debug 文件(包含所有递归依赖的基础环境)..." : > "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/info_debug" 2>/dev/null || true for BASENAME in "${BASENAMES[@]}"; do -    echo "$BASENAME" >> "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/info_debug" -    log.info "  写入: $BASENAME" + echo "$BASENAME" >> "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/info_debug" + log.info " 写入: $BASENAME" done # 创建 postrm 脚本 @@ -623,15 +622,15 @@ cat > "$PKG_BUILD_DIR/DEBIAN/postrm" << 'EOF' PACKAGE_NAME="$DPKG_MAINTSCRIPT_PACKAGE" if [ "$1" = "remove" ] || [ "$1" = "purge" ]; then -    echo "清理卸载残留" -    rm -rf "/var/lib/apm/$PACKAGE_NAME" -    for username in $(ls /home); do -        if [ -d "/home/$username/.apm/$PACKAGE_NAME" ]; then -            rm -fr "/home/$username/.apm/$PACKAGE_NAME" -        fi -    done + echo "清理卸载残留" + rm -rf "/var/lib/apm/$PACKAGE_NAME" + for username in $(ls /home); do + if [ -d "/home/$username/.apm/$PACKAGE_NAME" ]; then + rm -fr "/home/$username/.apm/$PACKAGE_NAME" + fi + done else -    echo "非卸载,跳过清理" + echo "非卸载,跳过清理" fi EOF @@ -642,20 +641,20 @@ log.info "复制文件到新的APM包..." # 如果是手动模式且没有DEB文件,进行交互式文件选择 if [ "$MANUAL_MODE" = true ] && [ -z "$DEB_PATH" ]; then -    interactive_copy_entries + interactive_copy_entries fi # 复制 /usr/share 内容到 entries if [ -d "$CRAFT_DIR/extract/usr/share" ]; then -    log.info "复制 /usr/share 内容..." -    mkdir -p "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/entries" -    cp -r "$CRAFT_DIR/extract/usr/share/"* "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/entries/" 2>/dev/null || true + log.info "复制 /usr/share 内容..." + mkdir -p "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/entries" + cp -r "$CRAFT_DIR/extract/usr/share/"* "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/entries/" 2>/dev/null || true fi # 复制 /opt/apps//entries(如果存在) if [ -n "$ORIG_PKGNAME" ] && [ -d "$CRAFT_DIR/extract/opt/apps/$ORIG_PKGNAME/entries" ]; then -    log.info "复制 /opt/apps/$ORIG_PKGNAME/entries 内容..." -    cp -r "$CRAFT_DIR/extract/opt/apps/$ORIG_PKGNAME/entries/"* "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/entries/" 2>/dev/null || true + log.info "复制 /opt/apps/$ORIG_PKGNAME/entries 内容..." + cp -r "$CRAFT_DIR/extract/opt/apps/$ORIG_PKGNAME/entries/"* "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/entries/" 2>/dev/null || true fi # 复制融合环境(core, work)到新的包内 files(以便运行时使用) @@ -672,12 +671,12 @@ cleanup_mount # 8. 计算目录大小函数 calculate_directory_size() { -    local dir="$1" -    if [ -d "$dir" ]; then -        du -sk "$dir" | cut -f1 -    else -        echo "0" -    fi + local dir="$1" + if [ -d "$dir" ]; then + du -sk "$dir" | cut -f1 + else + echo "0" + fi } # 构建依赖字符串 - 包含所有用户原始输入的 base(用于 control) @@ -685,10 +684,10 @@ DEPENDS_STR=$(IFS=,; echo "${BASENAMES_ORIG[*]}") # 若打包前没有 NEW_PKGNAME/NEW_VERSION,交互询问(一般出现在手动无DEB场景) if [ -z "$NEW_PKGNAME" ]; then -    read -r -p "请输入要创建的包名 (Package): " NEW_PKGNAME + read -r -p "请输入要创建的包名 (Package): " NEW_PKGNAME fi if [ -z "$NEW_VERSION" ] || [[ "$NEW_VERSION" == "-apm" ]]; then -    read -r -p "请输入要创建的版本 (Version): " NEW_VERSION + read -r -p "请输入要创建的版本 (Version): " NEW_VERSION fi # 创建 control 文件 @@ -700,16 +699,16 @@ Maintainer: APM Converter Depends: $DEPENDS_STR Installed-Size: $(calculate_directory_size "$PKG_BUILD_DIR") Description: APM converted package from ${ORIG_PKGNAME:-original} -  This package was automatically converted from the original deb package. -  Based on: ${BASENAMES_ORIG[*]} + This package was automatically converted from the original deb package. + Based on: ${BASENAMES_ORIG[*]} EOF # 9. 打包并生成输出文件名 OUTPUT_DEB="${NEW_PKGNAME}_${NEW_VERSION}_${ORIG_ARCH}.deb" log.info "开始使用 fakeroot 打包: $OUTPUT_DEB" fakeroot dpkg-deb -Z xz --build "$PKG_BUILD_DIR" "$OUTPUT_DEB" || { -    log.error "错误:打包 APM 包失败" -    exit 1 + log.error "错误:打包 APM 包失败" + exit 1 } log.info "转换完成!" @@ -723,4 +722,4 @@ log.info "基础环境(递归展开): ${BASENAMES[*]}" log.info "注意:桌面文件如存在已被修改,添加了 apm run 前缀和 X-APM-APPID" # 退出(trap 会触发 cleanup) -exit 0 \ No newline at end of file +exit 0