181 lines
7.0 KiB
Plaintext
181 lines
7.0 KiB
Plaintext
|
|
#!/usr/bin/env bash
|
|||
|
|
|
|||
|
|
# ==============================================================================
|
|||
|
|
# Function: apt (Smart Arch Package Manager Wrapper for Bash)
|
|||
|
|
# Description: Maps common Debian 'apt' commands to an intelligent Arch backend.
|
|||
|
|
# Features:
|
|||
|
|
# - Fallback routing: paru > yay > pacman.
|
|||
|
|
# - Automatic Sudo Handling: Prevents AUR helpers from running as root.
|
|||
|
|
# - Anti-Partial-Upgrade: Merges update/upgrade into a safe -Syu operation.
|
|||
|
|
# - Deep Clean Default: Merges remove/purge into -Rns for a pristine system.
|
|||
|
|
# - UI Integration: Progressive enhancement with 'shorin' for interactive modes.
|
|||
|
|
# - Safe orphan detection and i18n support.
|
|||
|
|
# - Highly readable, colorized, and column-aligned help output.
|
|||
|
|
# Usage: apt {update|upgrade|install [ui]|remove [ui]|search|show|autoremove|clean|help|-h} [pkg...]
|
|||
|
|
# ==============================================================================
|
|||
|
|
|
|||
|
|
# 启用严格模式:遇到错误退出、未定义变量退出、管道中任何命令失败则失败
|
|||
|
|
set -euo pipefail
|
|||
|
|
|
|||
|
|
# 1. 极简的 Locale 探测 (纯Bash字符串匹配)
|
|||
|
|
is_zh=0
|
|||
|
|
if [[ "${LC_ALL:-}" == zh_* || "${LC_MESSAGES:-}" == zh_* || "${LANG:-}" == zh_* ]]; then
|
|||
|
|
is_zh=1
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 2. 探测 shorin UI 工具是否存在
|
|||
|
|
has_shorin=0
|
|||
|
|
if command -v shorin >/dev/null 2>&1; then
|
|||
|
|
has_shorin=1
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 3. 参数解析与默认行为
|
|||
|
|
if [[ $# -eq 0 ]]; then
|
|||
|
|
action="help"
|
|||
|
|
exit_code=1
|
|||
|
|
else
|
|||
|
|
action="$1"
|
|||
|
|
shift # 移除第一个参数,将剩余参数传给对应的命令
|
|||
|
|
exit_code=0
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 定义 ANSI 颜色转义序列 (KISS原则:不依赖 tput)
|
|||
|
|
c_cmd=$'\033[36m' # Cyan
|
|||
|
|
c_hl=$'\033[33m' # Yellow
|
|||
|
|
c_rst=$'\033[0m' # Reset
|
|||
|
|
|
|||
|
|
# 预定义基础错误信息 (本地化)
|
|||
|
|
msg_err_pkg="Error: Specify packages."
|
|||
|
|
msg_err_search="Error: Specify search term."
|
|||
|
|
msg_err_show="Error: Specify package to show."
|
|||
|
|
|
|||
|
|
if [[ "$is_zh" -eq 1 ]]; then
|
|||
|
|
msg_err_pkg="错误:请指定要操作的软件包。"
|
|||
|
|
msg_err_search="错误:请指定搜索词。"
|
|||
|
|
msg_err_show="错误:请指定要查看的软件包。"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 4. 帮助信息拦截与本地化排版
|
|||
|
|
if [[ "$action" == "help" || "$action" == "-h" || "$action" == "--help" ]]; then
|
|||
|
|
if [[ "$is_zh" -eq 1 ]]; then
|
|||
|
|
echo "Arch 包管理器包装器 (优先级: ${c_hl}paru > yay > pacman${c_rst})"
|
|||
|
|
echo "用法: ${c_hl}apt${c_rst} <命令> [软件包...]"
|
|||
|
|
echo ""
|
|||
|
|
echo "命令:"
|
|||
|
|
echo " ${c_cmd}update(upgrade)${c_rst} 同步数据库并更新系统 (-Syu)"
|
|||
|
|
echo " ${c_cmd}install ${c_rst} 安装软件包 (-S)"
|
|||
|
|
if [[ "$has_shorin" -eq 1 ]]; then
|
|||
|
|
echo " ${c_cmd}install ui ${c_rst} 打开交互式界面安装 (依赖: shorin-contrib-git)"
|
|||
|
|
fi
|
|||
|
|
echo " ${c_cmd}remove ${c_rst} 彻底卸载软件包、依赖及配置文件 (-Rns)"
|
|||
|
|
if [[ "$has_shorin" -eq 1 ]]; then
|
|||
|
|
echo " ${c_cmd}remove ui ${c_rst} 打开交互式界面卸载 (依赖: shorin-contrib-git)"
|
|||
|
|
fi
|
|||
|
|
echo " ${c_cmd}search ${c_rst} 搜索软件包 (-Ss)"
|
|||
|
|
echo " ${c_cmd}show ${c_rst} 显示软件包详细信息 (-Si)"
|
|||
|
|
echo " ${c_cmd}autoremove ${c_rst} 安全地清理系统中的孤立软件包"
|
|||
|
|
echo " ${c_cmd}clean ${c_rst} 清理下载缓存 (-Sc)"
|
|||
|
|
echo " ${c_cmd}help, -h ${c_rst} 显示此帮助信息"
|
|||
|
|
else
|
|||
|
|
echo "Smart Arch Package Wrapper (Routing: ${c_hl}paru > yay > pacman${c_rst})"
|
|||
|
|
echo "Usage: ${c_hl}apt${c_rst} <command> [package...]"
|
|||
|
|
echo ""
|
|||
|
|
echo "Commands:"
|
|||
|
|
echo " ${c_cmd}update(upgrade)${c_rst} Sync databases and update system (Safe -Syu)"
|
|||
|
|
echo " ${c_cmd}install ${c_rst} Install packages (-S)"
|
|||
|
|
if [[ "$has_shorin" -eq 1 ]]; then
|
|||
|
|
echo " ${c_cmd}install ui ${c_rst} Open interactive installation UI (shorin pac)"
|
|||
|
|
fi
|
|||
|
|
echo " ${c_cmd}remove ${c_rst} Remove packages, unneeded dependencies, and configs (-Rns)"
|
|||
|
|
if [[ "$has_shorin" -eq 1 ]]; then
|
|||
|
|
echo " ${c_cmd}remove ui ${c_rst} Open interactive removal UI (shorin pacr)"
|
|||
|
|
fi
|
|||
|
|
echo " ${c_cmd}search ${c_rst} Search for packages (-Ss)"
|
|||
|
|
echo " ${c_cmd}show ${c_rst} Show package details (-Si)"
|
|||
|
|
echo " ${c_cmd}autoremove ${c_rst} Remove orphaned packages safely"
|
|||
|
|
echo " ${c_cmd}clean ${c_rst} Clean package cache (-Sc)"
|
|||
|
|
echo " ${c_cmd}help, -h ${c_rst} Show this help message"
|
|||
|
|
fi
|
|||
|
|
exit "$exit_code"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 5. 核心路由与提权逻辑
|
|||
|
|
# 使用数组来存储命令,避免含有空格的参数被 Bash 错误拆分
|
|||
|
|
if command -v paru >/dev/null 2>&1; then
|
|||
|
|
pkg_mgr="paru"
|
|||
|
|
cmd=("paru")
|
|||
|
|
elif command -v yay >/dev/null 2>&1; then
|
|||
|
|
pkg_mgr="yay"
|
|||
|
|
cmd=("yay")
|
|||
|
|
else
|
|||
|
|
pkg_mgr="pacman"
|
|||
|
|
cmd=("sudo" "pacman")
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 6. 动作映射 (Action Mapping)
|
|||
|
|
case "$action" in
|
|||
|
|
update|upgrade)
|
|||
|
|
"${cmd[@]}" -Syu
|
|||
|
|
;;
|
|||
|
|
install)
|
|||
|
|
if [[ $# -eq 0 ]]; then echo "$msg_err_pkg"; exit 1; fi
|
|||
|
|
# 拦截 'install ui',条件:且只输入了 ui 一个参数,且系统存在 shorin
|
|||
|
|
if [[ "$1" == "ui" && $# -eq 1 && "$has_shorin" -eq 1 ]]; then
|
|||
|
|
shorin pac
|
|||
|
|
exit 0
|
|||
|
|
fi
|
|||
|
|
"${cmd[@]}" -S "$@"
|
|||
|
|
;;
|
|||
|
|
remove)
|
|||
|
|
if [[ $# -eq 0 ]]; then echo "$msg_err_pkg"; exit 1; fi
|
|||
|
|
# 拦截 'remove ui'
|
|||
|
|
if [[ "$1" == "ui" && $# -eq 1 && "$has_shorin" -eq 1 ]]; then
|
|||
|
|
shorin pacr
|
|||
|
|
exit 0
|
|||
|
|
fi
|
|||
|
|
"${cmd[@]}" -Rns "$@"
|
|||
|
|
;;
|
|||
|
|
search)
|
|||
|
|
if [[ $# -eq 0 ]]; then echo "$msg_err_search"; exit 1; fi
|
|||
|
|
"$pkg_mgr" -Ss "$@"
|
|||
|
|
;;
|
|||
|
|
show)
|
|||
|
|
if [[ $# -eq 0 ]]; then echo "$msg_err_show"; exit 1; fi
|
|||
|
|
"$pkg_mgr" -Si "$@"
|
|||
|
|
;;
|
|||
|
|
autoremove)
|
|||
|
|
# 巧妙处理: pacman -Qtdq 找不到包时会返回退出码1,使用 || true 避免触发 set -e 导致脚本直接终止
|
|||
|
|
orphans=$(pacman -Qtdq || true)
|
|||
|
|
|
|||
|
|
if [[ -n "$orphans" ]]; then
|
|||
|
|
# 使用 mapfile 将多行字符串转换为安全数组,精准统计数量
|
|||
|
|
mapfile -t orphan_arr <<< "$orphans"
|
|||
|
|
if [[ "$is_zh" -eq 1 ]]; then
|
|||
|
|
echo "找到 ${#orphan_arr[@]} 个孤立的软件包。正在通过 $pkg_mgr 卸载..."
|
|||
|
|
else
|
|||
|
|
echo "Found ${#orphan_arr[@]} orphaned package(s). Removing via $pkg_mgr..."
|
|||
|
|
fi
|
|||
|
|
"${cmd[@]}" -Rns "${orphan_arr[@]}"
|
|||
|
|
else
|
|||
|
|
if [[ "$is_zh" -eq 1 ]]; then
|
|||
|
|
echo "系统很干净,没有需要清理的孤立软件包。"
|
|||
|
|
else
|
|||
|
|
echo "System is clean. No orphaned packages to remove."
|
|||
|
|
fi
|
|||
|
|
fi
|
|||
|
|
;;
|
|||
|
|
clean)
|
|||
|
|
"${cmd[@]}" -Sc
|
|||
|
|
;;
|
|||
|
|
*)
|
|||
|
|
if [[ "$is_zh" -eq 1 ]]; then
|
|||
|
|
echo "错误:不支持的 apt 命令映射: $action"
|
|||
|
|
echo "运行 'apt -h' 查看可用命令。"
|
|||
|
|
else
|
|||
|
|
echo "Error: Unsupported apt command mapped: $action"
|
|||
|
|
echo "Run 'apt -h' for valid commands."
|
|||
|
|
fi
|
|||
|
|
exit 1
|
|||
|
|
;;
|
|||
|
|
esac
|