给 pacman 增加子命令 —— 在 Arch Linux 上像使用 apt、dnf 那样使用 pacman 或 AUR helper

给 pacman 增加子命令 —— 在 Arch Linux 上像使用 apt、dnf 那样使用 pacman 或 AUR helper

用过 Arch 的都知道其包管理器 pacman 以及很多“AUR helper”如 yay、paru 等,使用的 -S 形式的“选项”(OPTIONS)作为参数。这和主流的 apt、dnf/yum 等的“子命令”式参数有着明显差异,很多新接触的都是一脸懵逼,比如最经典的 -S-Sy-Syy-Syu-Syyu-Syuu 这一连串看着类似的选项。

很多人就算用 Arch 挺长时间也根本不知道什么意思,就是入门时看的什么“小白教材”这么写就这么一直用了。

其实 apt 和 dnf/yum 的“底层” —— dpkg、rpm 也是选项式的,而他们作为直接与用户交互的封装都使用了子命令式,说明子命令应该对大部分人来说是更易使用的,因为它更“human-readable”。所以简单写了个脚本,让用户也可以像 apt 那样在 pacman 或 yay 等 AUR helper 中使用子命令。

可以保存并命名为 pkg 之类的进行使用。记得给运行权限并放进环境变量。普通用户使用时也不用加 sudo,这样一是为了方便,二是为了兼容那些 AUR helper 。

真要想标题里那样就是给 pacman 加子命令那也可以命名为 pacman,已经过简单测试,不过并不推荐这么做。

#!/bin/sh

get_arch_pkg() {
    local pkgs="yay paru /bin/pacman"
    for p in $pkgs; do
        if command -v "$p" >/dev/null; then
            pkg="$p"
            return 0
        fi
    done
    echo "not find package manager" && exit 1
}
no_subcmd() {
    echo "Please use \"$(basename $0) help\" to see detailed usage."
    echo "The package manager is $pkg"
    echo "Now will executing $pkg."
    echo
    $pkg
    exit 0
}
# Subcommands for pacman/yay/paru
pacman_like() {
    sub_cmd="$1"
    shift
    case $sub_cmd in
        "search") $pkg -Ss $@ ;;
        "show") $pkg -Si $@ ;; # from repo
        "info") $pkg -Qi $@ ;; # from local
        "clean") $sudo_prefix$pkg -Sc $@ ;;
        "update")
            echo 'Avoid doing partial upgrades. Always use upgrade(-Syu) instead of update(-Sy).'
            echo 'Refer to https://wiki.archlinux.org/title/System_maintenance 3.2 3.3'
            echo '请避免部分更新,不要运行 update(-Sy),而是运行 upgrade(-Syu)。'
            echo '请参阅 https://wiki.archlinuxcn.org/wiki/系统维护 3.2 3.3'
            $sudo_prefix$pkg -Sy $@
            ;;
        "install" | "add")
            case "$@" in
                ./*) $sudo_prefix$pkg -U $@ ;; # install local package
                *) $sudo_prefix$pkg -S $@ ;;
            esac
            ;;
        "upgrade") $sudo_prefix$pkg -Syu $@ ;;
        "force-upgrade") $sudo_prefix$pkg -Syyu $@ ;;
        "remove" | "del"* | "uninstall")
            echo Suggest using "purge" or "autopurge"
            $sudo_prefix$pkg -R $@
            ;;
        "purge") $sudo_prefix$pkg -Rn $@ ;;
        "autoremove" | "autopurge")
            if [ $# -eq 0 ]; then
                # from https://wiki.archlinuxcn.org/wiki/Pacman/提示和技巧 1.6
                $pkg -Qtdq | $sudo_prefix$pkg -Rns -
            else
                [ "$sub_cmd" = "autoremove" ] && $sudo_prefix$pkg -Rcs $@
                [ "$sub_cmd" = "autopurge" ] && $sudo_prefix$pkg -Rncs $@
            fi
            ;;
        "help")
            echo "可用子命令(Available subcommands):"
            echo "    search         : Search for packages"
            echo "    show           : Show package information from repo"
            echo "    info           : Show package information from local"
            echo "    clean          : Clean package cache"
            echo "    install        : Install packages"
            echo "     |- add"
            echo "    upgrade        : Upgrade packages"
            echo "    force-upgrade  : Force upgrade packages"
            echo "    remove         : Remove packages"
            echo "     |- del"
            echo "     |- uninstall"
            echo "    purge          : Purge packages"
            echo "    autoremove     : Automatically remove unneeded packages"
            echo "    autopurge      : Automatically purge unneeded packages"
            ;;
        *) $pkg $sub_cmd $@ ;;
    esac
}

get_arch_pkg

# need sudo or not
[ $(id -u) != 0 ] && [ "$pkg" = "/bin/pacman" ] && sudo_prefix="sudo " || sudo_prefix=""

[ $# -eq 0 ] && no_subcmd || pacman_like "$@"