#!/bin/bash VERSION=1.1.4 # 获取脚本名称用于帮助信息 SCRIPT_NAME=$(basename "$0") PATH_PREFIX=/var/lib/apm/apm/files/ace-env/ 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.debug() { echo -e "[\e[32mDEBUG\e[0m]: \e[1m$*\e[0m"; } # 帮助信息函数 show_help() { cat < 运行指定软件包的可执行文件 sandbox-run 运行指定软件包的可执行文件(主目录沙箱化) bwrap-run 运行指定软件包的可执行文件(使用特殊的挂载参数以支持bwrap) update 更新软件包信息 hold 锁定软件包版本 unhold 解锁软件包版本 full-upgrade 升级全部软件包 list 查看可用软件包信息 search 搜索软件包 download 下载包 show 展示包信息 clean 清除缓存软件包 autoremove 自动移除不需要的包 ssaudit 使用 ssaudit 进行本地软件安装,详情见 spark-store debug 显示调试系统信息并进入调试环境 amber 彩蛋功能 xmp360 彩蛋功能 bronya 彩蛋功能 -h, --help 显示此帮助信息 -v, --version 展示APM版本号 本 APM具有兔兔伯爵,女武神装甲和大运汽车。 EOF } apm_exec(){ # 递归读取info文件并构建lowerdir local lowerdirs=() local current_dir="${PATH_PREFIX}/var/lib/apm/${coredir}" # 当前目录开始 local next_info_file="" # 使用统一的 ace-run 脚本 APM_RUN_EXEC=/var/lib/apm/apm/files/ace-run while : ; do # 构建info文件的路径 next_info_file="${current_dir}/info" # echo "${current_dir}/info" # 检查info文件是否存在 if [[ ! -f "$next_info_file" ]]; then # log.debug "No more info files found, stopping recursion." break fi # 读取info文件的每一行并构建lowerdir while IFS= read -r basedir; do [[ -z "$basedir" ]] && continue # 跳过空行 # 检查ace-env目录是否存在 if [[ -d "${PATH_PREFIX}/var/lib/apm/${basedir}/files/ace-env" ]]; then lowerdirs+=("${PATH_PREFIX}/var/lib/apm/${basedir}/files/ace-env") # 如果ace-env不存在,检查core目录 elif [[ -d "${PATH_PREFIX}/var/lib/apm/${basedir}/files/core" ]]; then lowerdirs+=("${PATH_PREFIX}/var/lib/apm/${basedir}/files/core") else log.warn "Neither ace-env nor core directory found for base: $basedir" fi done < "$next_info_file" # 尝试获取下一个依赖信息的路径 local next_basedir=$(tail -n 1 "$next_info_file") if [[ -z "$next_basedir" || ! -d "${PATH_PREFIX}/var/lib/apm/${next_basedir}" ]]; then log.debug "No further dependencies found, ending recursion." break fi # 更新当前目录,递归处理下一个依赖 current_dir="${PATH_PREFIX}/var/lib/apm/${next_basedir}" done # 检查是否找到了有效的lowerdir if [[ ${#lowerdirs[@]} -eq 0 ]]; then log.error "No valid lower directories found for package: $coredir" return 1 fi # 将lowerdirs数组用冒号连接起来 local lowerdir=$(IFS=:; echo "${lowerdirs[*]}") # 创建挂载点目录 mkdir -p "/tmp/apm/${coredir}" # 使用fuse-overlayfs挂载 log.debug "Mounting with lowerdir: $lowerdir" fuse-overlayfs -o lowerdir="$lowerdir",upperdir="${PATH_PREFIX}/var/lib/apm/${coredir}/files/core/",workdir="${PATH_PREFIX}/var/lib/apm/${coredir}/files/work/" "/tmp/apm/${coredir}" # 执行命令 chrootEnvPath="/tmp/apm/${coredir}" ${APM_RUN_EXEC} "$@" # 卸载 umount "/tmp/apm/${coredir}" } # 调试信息函数 debug_info() { log.debug "======= APM Debug Information =======" log.debug "User: $(whoami)" log.debug "Hostname: $(hostname)" log.debug "OS: $(lsb_release -ds 2>/dev/null || uname -om)" log.debug "Kernel: $(uname -sr)" log.debug "Bash Version: ${BASH_VERSION}" log.debug "APT Version: $(apt --version | head -n1)" log.debug "APM APT Version: $(amber-pm-debug apt --version | head -n1)" log.debug "=====================================" amber-pm-debug "$@" } # 彩蛋函数 amber_egg() { cat <<'EOF' ____ ____ / __ )____ __________ ____ / __ )__ ______ ____ __ __ / __ / __ `/ ___/ __ \/ __ \ / __ / / / / __ \/ __ \/ / / / / /_/ / /_/ / / / /_/ / / / / / /_/ / /_/ / / / / / / / /_/ / /_____/\__,_/_/ \____/_/ /_/ /_____/\__,_/_/ /_/_/ /_/\__, / /____/ Amber Package Manager - Sparkling with magic! 安柏包管理器 - blingbling~ 💎 Another target tracked down by Outrider Amber! 侦察骑士,发现目标! EOF } bronya_egg() { cat <<'EOF' _ __ ____ _ ____ __ | | / /__ _/ / /____ ______(_)__ / __/_ _____ / /____ __ _ | |/ / _ `/ / '_/ // / __/ / -_) _\ \/ // (_-/dev/null 2>&1; then # 如果带前缀的目录不存在,尝试不带前缀的目录 if ls "/var/lib/apm/$pkg" >/dev/null 2>&1; then # 如果不带前缀的目录存在,清空 PATH_PREFIX PATH_PREFIX="" else # 如果两个目录都不存在,报错退出 log.error "Package not installed: $pkg" exit 1 fi fi coredir=$pkg export APM_PKG_NAME=$pkg # 检测是否有额外命令参数 if [ $# -gt 0 ]; then # 有额外参数:执行用户提供的命令 log.info "Running user command: $*" apm_exec "$@" else # 没有额外参数:提示 log.info "Usage: $SCRIPT_NAME run $pkg [EXEC_PATH]" exit 1 fi ;; sandbox-run) # 运行包命令:第二个参数必须是包名 export APM_USE_SANDBOX=1 shift $0 run "$@" ;; bwrap-run) # 运行包命令:使用特殊的挂载参数以支持bwrap export APM_USE_BWRAP=1 shift $0 run "$@" ;; debug) shift debug_info $@ ;; ssaudit) amber-pm-debug ssaudit $@ --native exit_code=$? if [ $exit_code -eq 0 ]; then log.info "Operation successful" else log.error "Error: Operation failed" exit $exit_code fi amber-pm-debug amber-pm-dstore-patch amber-pm-gxde-desktop-fix ;; -h|--help) show_help ;; -v|--version) echo "$VERSION" ;; amber) amber_egg ;; xmp360) xmp360_egg ;; bronya) bronya_egg ;; *) show_help ;; esac