pacman 命令详解与参数实测(Arch Linux rolling)

在 Arch Linux rolling(pacman 7.1.0)实测逐参数讲解 pacman:-S/-Sy/-Syy/-Syu/-Ss/-Si/-Sii/-Sw/-R/-Rs/-Rns/-Rdd/-Q 系/-F/-U/-D/-T/-Sc/-Scc/-b/--cachedir 全部常用操作与真实回显,覆盖 keyring 签名修复、软件源故障排障、HoldPkg/IgnorePkg/ParallelDownloads 配置实测与主流包管理器对照表。

Linux命令Linux系统Arch Linux命令行包管理2026/10/17

pacman 命令详解与参数实测(Arch Linux rolling)

目标:全面掌握 Arch Linux 包管理器 pacman 的每一个常用操作——-S 安装、-Sy/-Syy 刷新、-Syu 全量升级、-Ss 搜索、-Si/-Sii 信息、-Sw 仅下载、-R/-Rs/-Rns/-Rdd 移除、-Q 全家族查询、-F 文件查询、-U 本地包安装、-D 数据库操作、-T 依赖检查、-Sc/-Scc 缓存清理、-b/--cachedir 替代路径,以及 --noconfirm/--needed/--asdeps/--asexplicit 等修饰参数与 pacman.conf 核心配置项,全部命令与回显已在 Arch Linux rolling(pacman 7.1.0)实测通过。

一、环境信息

本文所有命令均在以下环境实测,回显逐字照抄:

  • 操作系统:Arch Linux(/etc/os-release 实测 BUILD_ID=rolling、VERSION_ID=20261011.0.609700)
  • 内核架构:x86_64(uname -m 实测)
  • 包管理器:pacman 7.1.0(实测包版本 pacman 7.1.0.r9.g54d9411-2,文中 -Syu 全量升级后为 7.1.0.r9.g54d9411-3),库版本 libalpm v16.0.1
  • 签名密钥环:archlinux-keyring 20260909-1
  • 初始状态:全新最小系统,已安装 137 个包,/var/lib/pacman/sync/ 与 /var/cache/pacman/pkg/ 均为空
  • 软件源:/etc/pacman.d/mirrorlist 共 2 条 Server(fastly 与 geo 两站点)
  • 执行身份:root
  • 演示包(体积小、便于反复装卸):tree 2.3.2-1、sl 5.05-6、cowsay 3.8.4-1(连带依赖 db5.3 5.3.28-7、perl 5.42.3-1)、figlet 2.2.5-6、htop 3.5.3-1
  • 拓展工具:pacman-contrib 1.13.1-1(rankmirrors/checkupdates 等脚本集)、fakeroot 1:1.37.2-3

💡 说明:pacman 是滚动发行版的包管理器,没有固定大版本号绑定发行版,本文所有结论以 pacman 7.1.0(libalpm 16)实测为准;rolling 环境下查询自己环境的精确版本用 pacman -Q pacman。

二、命令概览

2.1 操作模型与 --help 全量回显

pacman 的命令行模型是「一个大写操作 + 若干小写修饰参数」:pacman <operation> [options] [package(s)]。大写字母决定"做什么"(装/删/查/升级/校验),同一批小写参数在不同操作下语义不同(如 -s 在 -S 下是下载、在 -Q 下是本地搜索)。以下为 pacman --help 的完整实测输出:

$ pacman --help
usage:  pacman <operation> [...]
operations:
    pacman {-h --help}
    pacman {-V --version}
    pacman {-D --database} <options> <package(s)>
    pacman {-F --files}    [options] [file(s)]
    pacman {-Q --query}    [options] [package(s)]
    pacman {-R --remove}   [options] <package(s)>
    pacman {-S --sync}     [options] [package(s)]
    pacman {-T --deptest}  [options] [package(s)]
    pacman {-U --upgrade}  [options] [file(s)]

use 'pacman {-h --help}' with an operation for available options

8 个操作按功能分组:

操作全称用途
-Ssync与软件源同步:安装、刷新、升级、搜索、清理缓存
-Qquery查询本地已安装包:列表、详情、文件清单、属主反查
-Rremove移除已安装的包
-Uupgrade安装本地包文件或 URL(不经软件源解析)
-Ddatabase修改本地数据库元信息(安装原因标记、完整性检查)
-Ffiles基于文件数据库查询「哪个包提供某文件」(未安装也能查)
-Tdeptest依赖测试:检查给定依赖是否满足,不执行任何变更
-V/-hversion/help版本与帮助

每个操作都有独立的子帮助:pacman -S --help、pacman -Q --help 等(各操作帮助全文见 3.1/3.12/3.19/3.20/3.21/3.22 节对应位置)。

💡 说明:pacman 帮助里方括号 [filter] 标记的参数(如 -Qe/-Qdt)是过滤器——它们筛选 -Q 的输出范围;而 <options> 标记的参数(如 -Dk)是动作。理解这一点后,-Q 家族的十几个参数就能按"过滤"逻辑记忆。

2.2 版本信息

pacman --version
pacman -Q pacman
pacman -Q archlinux-keyring

实测回显(pacman --version):

$ pacman --version

 .--.                  Pacman v7.1.0 - libalpm v16.0.1
/ _.-' .-.  .-.  .-.   Copyright (C) 2006-2025 Pacman Development Team
\  '-. '-'  '-'  '-'   Copyright (C) 2002-2006 Judd Vinet
 '--'
                       This program may be freely redistributed under
                       the terms of the GNU General Public License.

实测回显(包版本,注意此时尚未同步过软件源数据库,-Q 会先打印两条警告):

$ pacman -Q pacman
warning: database file for 'core' does not exist (use '-Sy' to download)
warning: database file for 'extra' does not exist (use '-Sy' to download)
pacman 7.1.0.r9.g54d9411-2

$ pacman -Q archlinux-keyring
warning: database file for 'core' does not exist (use '-Sy' to download)
warning: database file for 'extra' does not exist (use '-Sy' to download)
archlinux-keyring 20260909-1

💡 说明:-Q 本来只查本地库,但 pacman -Q 不带参数列出全部已装包时需要对照软件源库标注 [installed] 信息,因此全新系统第一次执行会提示 database file for 'core' does not exist (use '-Sy' to download)——这不是故障,跑一次 pacman -Sy 即消失(3.4 节实测)。

2.3 测试数据准备

本文演示统一使用小体积包,安装状态随章节推进变化,每节开头注明当前状态。初始基线实测如下:

pacman -Q | wc -l                 # 已安装包总数
ls -l /var/lib/pacman/sync/       # 软件源数据库目录
ls -l /var/cache/pacman/pkg/      # 包缓存目录
grep -vE '^\s*(#|$)' /etc/pacman.conf    # pacman.conf 有效配置行
grep -E '^Server' /etc/pacman.d/mirrorlist   # 软件源列表

实测回显:

$ pacman -Q | wc -l
warning: database file for 'core' does not exist (use '-Sy' to download)
warning: database file for 'extra' does not exist (use '-Sy' to download)
137

$ ls -l /var/lib/pacman/sync/
total 0

$ ls -l /var/cache/pacman/pkg/
total 0

$ grep -vE '^\s*(#|$)' /etc/pacman.conf
[options]
HoldPkg     = pacman glibc
Architecture = auto
NoProgressBar
VerbosePkgLists
ParallelDownloads = 5
DownloadUser = alpm
DisableSandboxFilesystem
SigLevel    = Required DatabaseOptional
LocalFileSigLevel = Optional
[core]
Include = /etc/pacman.d/mirrorlist
[extra]
Include = /etc/pacman.d/mirrorlist
[options]
NoExtract  = usr/share/help/* !usr/share/help/en* !usr/share/help/C/*
NoExtract  = usr/share/gtk-doc/html/* usr/share/doc/*
NoExtract  = usr/share/locale/* usr/share/X11/locale/* usr/share/i18n/*
NoExtract   = !*locale*/en*/* !usr/share/i18n/charmaps/UTF-8.gz !usr/share/*locale*/locale.*
NoExtract   = !usr/share/*locales/en_?? !usr/share/*locales/i18n* !usr/share/*locales/iso*
NoExtract   = !usr/share/*locales/trans*
NoExtract   = !usr/share/X11/locale/C/*
NoExtract   = !usr/share/X11/locale/compose.dir !usr/share/X11/locale/iso8859-1/*
NoExtract  = !usr/share/*locales/C !usr/share/*locales/POSIX !usr/share/i18n/charmaps/ANSI_X3.4-1968.gz
NoExtract  = usr/share/man/* usr/share/info/*
NoExtract  = usr/share/vim/vim*/lang/*
NoExtract  = etc/pacman.conf etc/pacman.d/mirrorlist

$ grep -E '^Server' /etc/pacman.d/mirrorlist
Server = https://fastly.mirror.pkgbuild.com/$repo/os/$arch
Server = https://geo.mirror.pkgbuild.com/$repo/os/$arch

💡 说明:Server = .../$repo/os/$arch 中的 $repo、$arch 是 pacman 的内置变量,分别替换为软件仓库段名(core/extra)与架构(x86_64),一条模板同时服务多个仓库。HoldPkg = pacman glibc 是 Arch 默认激活的保护项(3.25 节实测)。另:pacman 7.x 的 /etc/pacman.conf 已不存在 SyncFirst 配置项(grep -n 'SyncFirst' /etc/pacman.conf 无命中,grep 退出码 1),该键是旧版 pacman 用于「同步前先升级指定包(如 keyring)」的机制,已被 archlinux-keyring 包自身的钩子机制取代。

三、参数逐项实测

3.1 -S:从软件源安装包

-S(sync)是 pacman 使用频率最高的操作:按名字从软件源安装包,自动解析并安装依赖。全新系统先 -Sy 同步一次(3.4 节详解),然后安装演示包 tree:

pacman -S --noconfirm tree
pacman -Q tree
tree --version

实测回显:

$ pacman -S --noconfirm tree
resolving dependencies...
looking for conflicting packages...

Package (1)  New Version  Net Change  Download Size

extra/tree   2.3.2-1        0.09 MiB       0.04 MiB

Total Download Size:   0.04 MiB
Total Installed Size:  0.09 MiB

:: Proceed with installation? [Y/n]
:: Retrieving packages...
 tree-2.3.2-1-x86_64 downloading...
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
:: Processing package changes...
installing tree...
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
exit=0

$ pacman -Q tree
tree 2.3.2-1

$ tree --version
tree v2.3.2 © 1996 - 2026 by Steve Baker, Thomas Moore, Francesc Rocher, Florian Sesser, Kyosuke Tokoro

一次安装多个包并观察依赖解析(sl 与 cowsay,cowsay 自动带入 perl、db5.3):

pacman -S --noconfirm sl cowsay
cowsay 'hello pacman'

实测回显:

$ pacman -S --noconfirm sl cowsay
resolving dependencies...
looking for conflicting packages...

Package (4)   New Version  Net Change  Download Size

core/db5.3    5.3.28-7       6.48 MiB       1.26 MiB
core/perl     5.42.3-1      70.34 MiB      20.49 MiB
extra/cowsay  3.8.4-1        0.04 MiB       0.02 MiB
extra/sl      5.05-6         0.03 MiB       0.01 MiB

Total Download Size:   21.78 MiB
Total Installed Size:  76.88 MiB

:: Proceed with installation? [Y/n]
:: Retrieving packages...
 perl-5.42.3-1-x86_64 downloading...
 db5.3-5.3.28-7-x86_64 downloading...
 cowsay-3.8.4-1-any downloading...
 sl-5.05-6-x86_64 downloading...
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
:: Processing package changes...
installing sl...
installing db5.3...
installing perl...
installing cowsay...
:: Running post-transaction hooks...
(1/2) Arming ConditionNeedsUpdate...
(2/2) Checking for old perl modules...
exit=0

$ cowsay 'hello pacman'
 ______________
< hello pacman >
 --------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

-S 的子帮助(pacman -S --help 全量实测,可见 -S 家族全部选项):

$ pacman -S --help
usage:  pacman {-S --sync} [options] [package(s)]
options:
  -b, --dbpath <path>  set an alternate database location
  -c, --clean          remove old packages from cache directory (-cc for all)
  -d, --nodeps         skip dependency version checks (-dd to skip all checks)
  -g, --groups         view all members of a package group
                       (-gg to view all groups and members)
  -i, --info           view package information (-ii for extended information)
  -l, --list <repo>    view a list of packages in a repo
  -p, --print          print the targets instead of performing the operation
  -q, --quiet          show less information for query and search
  -r, --root <path>    set an alternate installation root
  -s, --search <regex> search remote repositories for matching strings
  -u, --sysupgrade     upgrade installed packages (-uu enables downgrades)
  -v, --verbose        be verbose
  -w, --downloadonly   download packages but do not install/upgrade anything
  -y, --refresh        download fresh package databases from the server
                       (-yy to force a refresh even if up to date)
      --arch <arch>    set an alternate architecture
      --asdeps         install packages as non-explicitly installed
      --asexplicit     install packages as explicitly installed
      --assume-installed <package=version>
                       add a virtual package to satisfy dependencies
      --cachedir <dir> set an alternate package cache location
      --color <when>   colorize the output
      --config <path>  set an alternate configuration file
      --confirm        always ask for confirmation
      --dbonly         only modify database entries, not package files
      --debug          display debug messages
      --disable-download-timeout
                       use relaxed timeouts for download
      --disable-sandbox
                       disables all sandbox features used for the downloader process
      --disable-sandbox-filesystem
                       disables the filesystem part of the downloader process sandbox
      --disable-sandbox-syscalls
                       disables the syscalls part of the downloader process sandbox
      --gpgdir <path>  set an alternate home directory for GnuPG
      --hookdir <dir>  set an alternate hook location
      --ignore <pkg>   ignore a package upgrade (can be used more than once)
      --ignoregroup <grp>
                       ignore a group upgrade (can be used more than once)
      --logfile <path> set an alternate log file
      --needed         do not reinstall up to date packages
      --noconfirm      do not ask for any confirmation
      --noprogressbar  do not show a progress bar when downloading files
      --noscriptlet    do not execute the install scriptlet if one exists
      --overwrite <glob>
                       overwrite conflicting files (can be used more than once)
      --print-format <string>
                       specify how the targets should be printed
      --sysroot        operate on a mounted guest system (root-only)

💡 要点:

  1. 安装事务的完整流程固定为:resolving dependencies(依赖解析)→ looking for conflicting packages(冲突检查)→ 摘要表 → 确认 → 下载 → checking keyring(签名密钥)→ checking package integrity(包完整性)→ checking for file conflicts → 安装 → 事务钩子(Arming ConditionNeedsUpdate 提示 systemd 在下次启动时重建相关服务依赖)。写脚本判断成败看退出码:0 成功、1 一般错误。
  2. 摘要表 Package (4) 的 4 是最终事务里的包总数(显式目标 + 自动依赖);Net Change 是安装后磁盘净变化。自动依赖(db5.3/perl)与显式目标(sl/cowsay)都会列出,安装原因标记不同(见 3.21 节 -D)。
  3. 包名支持 仓库/包名 消歧写法(如 extra/tree);同名包在多个仓库时可显式指定仓库段。

3.2 --noconfirm:跳过全部确认(脚本必备)

--noconfirm 让 pacman 对所有 [Y/n] 询问直接采用方括号里的默认值应答。默认 [Y/n] 的问句会自动答 Y,[y/N] 的问句会自动答 N(这个语义差异在 3.24 节 -Scc 有一个真实的坑)。对比演示:不加 --noconfirm 时用管道回答 n 中止安装:

printf 'n\n' | pacman -S sl
echo "exit=$?"
pacman -Q sl

实测回显:

$ printf 'n\n' | pacman -S sl
resolving dependencies...
looking for conflicting packages...

Package (1)  New Version  Net Change  Download Size

extra/sl     5.05-6         0.03 MiB       0.01 MiB

Total Download Size:   0.01 MiB
Total Installed Size:  0.03 MiB

:: Proceed with installation? [Y/n] n
exit=1

$ pacman -Q sl
error: package 'sl' was not found
Q_exit=1

💡 要点:

  1. 回答 n 后事务中止,退出码 1,什么都没装;回答 y(或直接回车,取默认值 Y)才会继续。
  2. 脚本/无人值守场景还有个隐蔽坑:pacman 的确认读的是 stdin,若脚本运行环境 stdin 是关闭状态(EOF),事务会直接中止并退出 1——本文实测环境中 pacman -Sy archlinux-keyring(不带 --noconfirm)就因 stdin EOF 中止,exit=1。所以自动化场景必须显式加 --noconfirm(或 printf 'y\n' |)。
  3. --noconfirm 是「按默认值应答」而不是「全部答 yes」:[y/N] 形态的问句(如 -Scc 的"是否清空全部缓存")默认是 N,加了 --noconfirm 也照样跳过(3.24 节实测留档)。

3.3 --needed:同版本包跳过重装

--needed 让 pacman 对已安装且版本不旧的包跳过,避免无谓重装。实测对比(tree 已安装 2.3.2-1):

pacman -S --needed --noconfirm tree
pacman -S --noconfirm tree

实测回显(带 --needed,跳过):

$ pacman -S --needed --noconfirm tree
warning: tree-2.3.2-1 is up to date -- skipping
 there is nothing to do

实测回显(不带 --needed,默认重装):

$ pacman -S --noconfirm tree
resolving dependencies...
warning: tree-2.3.2-1 is up to date -- reinstalling
looking for conflicting packages...

Package (1)  Old Version  New Version  Net Change

extra/tree   2.3.2-1      2.3.2-1        0.00 MiB

Total Installed Size:  0.09 MiB
Net Upgrade Size:      0.00 MiB

:: Proceed with installation? [Y/n]
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
:: Processing package changes...
reinstalling tree...
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...

💡 要点:-S 默认对同版本包执行重装(reinstalling),--needed 则输出 is up to date -- skipping 与 there is nothing to do。批量脚本里给 -S 永远带上 --needed 是个好习惯:幂等、省流量、不覆盖已调好的包内配置。需要强制重装(如文件被误删)时反着来:去掉 --needed 或用 pacman -S pkg 显式重装。

3.4 -Sy / -Syy:刷新软件源数据库

-Sy 从软件源下载最新的包数据库(core.db/extra.db)到 /var/lib/pacman/sync/;-Syy 强制重新下载(即使本地已是最新),用于刚切换软件源的场景。全新系统实测 -Sy:

pacman -Sy
ls -l /var/lib/pacman/sync/
pacman -Syy

实测回显:

$ pacman -Sy
:: Synchronizing package databases...
 core downloading...
 extra downloading...
exit=0

$ ls -l /var/lib/pacman/sync/
total 104
-rw-r--r-- 1 root root  135785 Oct 16 16:18 core.db
-rw-r--r-- 1 root root 1472365 Oct 16 16:18 extra.db

$ pacman -Syy
:: Synchronizing package databases...
 core downloading...
 extra downloading...
exit=0

💡 要点:

  1. -Sy 后本地 .db 就位,2.2 节那两条 database file for 'core' does not exist 警告随之消失。-Syy 与 -Sy 输出相同,区别是 -Syy 不比对本地时间戳、无条件重新下载(换软件源后必用,防止新旧源数据库混用)。
  2. ⚠️ Arch 滚动发行版不支持部分升级:单独 -Sy 后数据库已是最新,但系统里的包还是旧的,此时再 -S 某包 可能因依赖版本不匹配而失败。正确习惯是把 -Sy 与 -u(升级)连用,即日常更新一律 pacman -Syu(3.5 节);装包也建议 pacman -Syu 包名 一步到位。
  3. -F 家族也有对应的 -Fy(下载文件数据库),与 -Sy 相互独立(3.19 节)。

3.5 -Syu:全量升级系统

-Syu = 刷新数据库(-y)+ 升级所有已安装包(-u)。本次实测环境刚好有 5 个包有新版本(curl/libarchive/pacman/sqlite/zlib),是真实升级事务:

pacman -Syu --noconfirm
pacman -Qu

实测回显:

$ pacman -Syu --noconfirm
:: Synchronizing package databases...
 core downloading...
 extra downloading...
:: Starting full system upgrade...
resolving dependencies...
looking for conflicting packages...

Package (5)      Old Version          New Version          Net Change  Download Size

core/curl        8.22.0-1             8.23.0-1               0.01 MiB       1.31 MiB
core/libarchive  3.8.9-1              3.8.10-1               0.01 MiB       0.57 MiB
core/pacman      7.1.0.r9.g54d9411-2  7.1.0.r9.g54d9411-3    0.00 MiB       0.95 MiB
core/sqlite      3.53.4-1             3.54.0-1               0.18 MiB       2.39 MiB
core/zlib        1:1.3.2-3            1:1.3.2-4              0.00 MiB       0.08 MiB

Total Download Size:    5.30 MiB
Total Installed Size:  25.79 MiB
Net Upgrade Size:       0.21 MiB

:: Proceed with installation? [Y/n]
:: Retrieving packages...
 sqlite-3.54.0-1-x86_64 downloading...
 curl-8.23.0-1-x86_64 downloading...
 pacman-7.1.0.r9.g54d9411-3-x86_64 downloading...
 libarchive-3.8.10-1-x86_64 downloading...
 zlib-1:1.3.2-4-x86_64 downloading...
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
:: Processing package changes...
upgrading zlib...
upgrading sqlite...
upgrading curl...
upgrading libarchive...
upgrading pacman...
:: Running post-transaction hooks...
(1/4) Creating system user accounts...
(2/4) Reloading system manager configuration...
  Skipped: Current root is not booted.
(3/4) Enqueuing marked services...
  Skipped: Current root is not booted.
(4/4) Arming ConditionNeedsUpdate...
exit=0

$ pacman -Qu
qu_exit=1

💡 要点:

  1. 升级后 pacman -Qu(可升级列表)为空、退出码 1("无输出"即"无可升级"),见 3.18 节语义说明。
  2. 事务钩子里的 Reloading system manager configuration... Skipped: Current root is not booted. 是钩子调用 systemd 系统管理器时的如实输出:当前运行环境未以完整系统管理器引导,钩子跳过,不影响包升级结果;在完整引导的 Arch 服务器上这两步会真正执行。
  3. -uu(双 u)允许降级:当软件源里的版本比本地旧时(如回滚源),普通 -Syu 会跳过,-Syuu 会把本地较新的包降回源版本,慎用。

3.6 -Ss:搜索软件源

-Ss 用正则在软件源数据库里搜包名与描述(此时无需联网,查的是 3.4 节下载的本地库):

pacman -Ss '^sl$'
pacman -Ss cowsay

实测回显:

$ pacman -Ss '^sl$'
extra/sl 5.05-6
    Steam Locomotive runs across your terminal when you type "sl" as you meant to type "ls"

$ pacman -Ss cowsay
extra/botsay 1.4.4-1
    Like cowsay, but with randomly generated ASCII robots and color support
extra/cowsay 3.8.4-1
    Configurable talking cow (and a bit more)
extra/ponysay 3.0.3-7
    cowsay reimplemention for ponies

💡 要点:参数值是扩展正则:^sl$ 精确匹配包名;裸关键字(cowsay)同时匹配包名与描述。结果每条两行:第一行 仓库/包名 版本,第二行缩进描述。加 -q 只输出 仓库/包名 一行;想看仓库里某个包的完整信息用 -Si(3.7 节)。

3.7 -Si / -Sii:查看仓库包信息

-Si 显示软件源中某包的元信息;-Sii 追加依赖反向关系与校验和细节:

pacman -Si tree
pacman -Sii tree

实测回显(-Si):

$ pacman -Si tree
Repository      : extra
Name            : tree
Version         : 2.3.2-1
Description     : A directory listing program displaying a depth indented list of files
Architecture    : x86_64
URL             : https://gitlab.com/OldManProgrammer/unix-tree
Licenses        : GPL-2.0-or-later
Groups          : None
Provides        : None
Depends On      : glibc
Optional Deps   : None
Conflicts With  : None
Replaces        : None
Download Size   : 43.52 KiB
Installed Size  : 94.00 KiB
Packager        : Jelle van der Waa <jelle@archlinux.org>
Build Date      : Sun Mar 29 14:23:02 2026
Validated By    : SHA-256 Sum  Signature

实测回显(-Sii,多出的字段为 Required By/Optional For/MD5 Sum/SHA-256 Sum/Signatures/Extended Data):

$ pacman -Sii tree
Repository      : extra
Name            : tree
Version         : 2.3.2-1
Description     : A directory listing program displaying a depth indented list of files
Architecture    : x86_64
URL             : https://gitlab.com/OldManProgrammer/unix-tree
Licenses        : GPL-2.0-or-later
Groups          : None
Provides        : None
Depends On      : glibc
Optional Deps   : None
Required By     : pass
Optional For    : inxi
Conflicts With  : None
Replaces        : None
Download Size   : 43.52 KiB
Installed Size  : 94.00 KiB
Packager        : Jelle van der Waa <jelle@archlinux.org>
Build Date      : Sun Mar 29 14:23:02 2026
MD5 Sum         : None
SHA-256 Sum     : 8a6230468cc31a2c984a41c092035dd16bf97e737ec3241490724a5419903739
Signatures      : C06086337C50773E
Extended Data   : None

💡 要点:-Si 看的是软件源视角(仓库里有什么、多大、谁打包的),-Qi(3.14 节)看的是本地已安装视角(装没装、何时装、安装原因)。Signatures: C06086337C50773E 是打包者密钥指纹前 16 位,与 3.27 节 keyring 修复时的签名者完全对应。-Si 之前需要有 -Sy 下载过数据库。

3.8 -Sw:仅下载不安装

-Sw(-w = downloadonly)把包文件下载到缓存目录但不安装,适合离线分发、备份包文件或先审后装:

pacman -Sw --noconfirm htop
pacman -Q htop
ls -l /var/cache/pacman/pkg/ | grep htop

实测回显:

$ pacman -Sw --noconfirm htop
resolving dependencies...

Package (1)  New Version  Net Change  Download Size

extra/htop   3.5.3-1        0.41 MiB       0.18 MiB

Total Download Size:  0.18 MiB

:: Proceed with download? [Y/n]
:: Retrieving packages...
 htop-3.5.3-1-x86_64 downloading...
checking keyring...
checking package integrity...
exit=0

$ pacman -Q htop
error: package 'htop' was not found
Q_exit=1

$ ls -l /var/cache/pacman/pkg/ | grep htop
-rw-r--r-- 1 root root 184319 Aug 16 16:16 htop-3.5.3-1-x86_64.pkg.tar.zst
-rw-r--r-- 1 root root     119 Aug 16 16:16 htop-3.5.3-1-x86_64.pkg.tar.zst.sig

💡 要点:确认问句是 :: Proceed with download? [Y/n](不是 installation),下载完成只做签名校验、没有 loading package files/安装步骤;pacman -Q htop 依旧报 not found 证明未安装。下载落点是 /var/cache/pacman/pkg/ 的 .pkg.tar.zst 与配套 .sig,后续可直接 pacman -U 离线安装(3.20 节正好用这份缓存演示)。

3.9 -R:移除单个包

-R 移除指定包本身,不动它带入的依赖(依赖是否还被别人需要是 -Rs 的事):

pacman -R --noconfirm sl
pacman -Q sl

实测回显:

$ pacman -R --noconfirm sl
checking dependencies...

Package (1)  Old Version  Net Change

sl           5.05-6        -0.03 MiB

Total Removed Size:  0.03 MiB

:: Do you want to remove these packages? [Y/n]
:: Processing package changes...
removing sl...
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
exit=0

$ pacman -Q sl
error: package 'sl' was not found

移除仍被依赖的包会被拒绝(perl 被 cowsay 依赖):

pacman -R --noconfirm perl

实测回显:

$ pacman -R --noconfirm perl
checking dependencies...
error: failed to prepare transaction (could not satisfy dependencies)
:: removing perl breaks dependency 'perl' required by cowsay
exit=1

💡 要点:-R 的事务有 checking dependencies 前置检查,会列出反向依赖并拒绝破坏性移除(breaks dependency ... required by ...),退出码 1。-R 的确认问句是 :: Do you want to remove these packages? [Y/n]。误删后补救很快:包文件还在缓存里(移除不清缓存),pacman -S 包名 重装即可。

3.10 -Rs / -Rns:连同不再被需要的依赖一起移除

-Rs 在移除目标的同时,把"因目标而装、现在没人需要"的依赖一并清掉;-Rns 再叠加 -n(--nosave,不保留备份的配置文件 .pacsave)。实测移除 htop:

pacman -Rs --noconfirm htop
pacman -Rns --noconfirm figlet

实测回显:

$ pacman -Rs --noconfirm htop
checking dependencies...

Package (1)  Old Version  Net Change

htop         3.5.3-1       -0.41 MiB

Total Removed Size:  0.41 MiB

:: Do you want to remove these packages? [Y/n]
:: Processing package changes...
removing htop...
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
exit=0

$ pacman -Rns --noconfirm figlet
checking dependencies...

Package (1)  Old Version  Net Change

figlet       2.2.5-6       -0.63 MiB

Total Removed Size:  0.63 MiB

:: Do you want to remove these packages? [Y/n]
:: Processing package changes...
removing figlet...
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
exit=0

再看一个能看出 -Rs 连带效果的例子:移除显式安装的 perl 时,自动依赖 db5.3 一并被带走,并提示 perl 还被哪些包可选依赖:

pacman -Rns --noconfirm perl

实测回显:

$ pacman -Rns --noconfirm perl
checking dependencies...
:: binutils optionally requires perl: for gprofng-display-html
:: glibc optionally requires perl: for mtrace
:: openssl optionally requires perl

Package (2)  Old Version  Net Change

db5.3        5.3.28-7      -6.48 MiB
perl         5.42.3-1     -70.34 MiB

Total Removed Size:  76.82 MiB

:: Do you want to remove these packages? [Y/n]
:: Processing package changes...
removing perl...
removing db5.3...
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
exit=0

💡 要点:

  1. Package (2) 里出现了 db5.3——它是当初装 cowsay 时自动带入的依赖(3.1 节),perl 走后无人需要,-Rs 顺手清掉,这就是"依赖回收"。上面的 optionally requires 行只是告知可选依赖关系,不阻止移除。
  2. -Rn(--nosave)默认关闭:普通 -R 会把被删包的配置文件改名保留为 .pacsave,-Rn 连这个备份都不留。生产机建议保留默认(不带 n),留一份旧配置更安全。
  3. -R 家族还有两个方向:-Rc(cascade,把依赖目标的包也删掉,破坏性大)与 -Ru(unneeded,只删"没人需要的"),日常清理用 -Rns 配合 -Qdt 即可(3.17 节)。

3.11 -Rdd:跳过依赖检查强行移除(破坏与修复实测)

-dd(双 d,--nodeps 两次)跳过所有依赖检查,包括"这个包还被别人需要"的检查。这是修复依赖死锁的最后手段,用完必须立刻修复。实测强移 cowsay 依赖的 perl:

pacman -Rdd --noconfirm perl
pacman -Qi cowsay | grep -A1 'Missing Dependencies'
cowsay 'test'
pacman -Dk

实测回显:

$ pacman -Rdd --noconfirm perl

Package (1)  Old Version  Net Change

perl         5.42.3-1     -70.34 MiB

Total Removed Size:  70.34 MiB

:: Do you want to remove these packages? [Y/n]
:: Processing package changes...
removing perl...
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
exit=0

$ pacman -Qi cowsay | grep -A1 'Missing Dependencies'
Missing Dependencies : perl

$ cowsay 'test'
env: ‘perl’: No such file or directory
run_exit=127

$ pacman -Dk
error: missing 'perl' dependency for 'cowsay'
dk_exit=1

修复:重装 perl,恢复一致状态:

pacman -S --noconfirm perl
pacman -Qi cowsay | grep -c 'Missing Dependencies'
cowsay 'repaired'

实测回显:

$ pacman -S --noconfirm perl
resolving dependencies...
looking for conflicting packages...

Package (1)  New Version  Net Change  Download Size

core/perl    5.42.3-1      70.34 MiB      20.49 MiB

Total Download Size:  20.49 MiB
Total Installed Size:  70.34 MiB

:: Proceed with installation? [Y/n]
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
:: Processing package changes...
installing perl...
:: Running post-transaction hooks...
(1/2) Arming ConditionNeedsUpdate...
(2/2) Checking for old perl modules...
exit=0

$ pacman -Qi cowsay | grep -c 'Missing Dependencies'
0

$ cowsay 'repaired'
 __________
< repaired >
 ----------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

💡 要点:

  1. -Rdd 跳过依赖检查后, cowsay 的元数据里留下 Missing Dependencies : perl(-Qi 可见),解释器直接跑不了(env: 'perl': No such file or directory,退出码 127);pacman -Dk 数据库健康检查也会报 error: missing 'perl' dependency for 'cowsay' 并以非零退出——这三处就是"系统已被强移搞破"的体检证据。
  2. 单个 -d 只跳过版本约束检查,-dd 才跳过全部依赖检查。-Rdd 的正确用途是"依赖关系已经损坏、普通 -R 拒绝执行"时的解锁手段,用完立即重装补齐(本文即演示此闭环),严禁当作常规卸载方式。

3.12 -Q:查询已安装包

-Q(query)查本地数据库:不带参数列出全部已安装包(包名 版本 两列)。先看 -Q 子帮助全量:

pacman -Q --help
pacman -Q | wc -l
pacman -Q | tail -6

实测回显(-Q --help 全量):

$ pacman -Q --help
usage:  pacman {-Q --query} [options] [package(s)]
options:
  -b, --dbpath <path>  set an alternate database location
  -c, --changelog      view the changelog of a package
  -d, --deps           list packages installed as dependencies [filter]
  -e, --explicit       list packages explicitly installed [filter]
  -g, --groups         view all members of a package group
  -i, --info           view package information (-ii for backup files)
  -k, --check          check that package files exist (-kk for file properties)
  -l, --list           list the files owned by the queried package
  -m, --foreign        list installed packages not found in sync db(s) [filter]
  -n, --native         list installed packages only found in sync db(s) [filter]
  -o, --owns <file>    query the package that owns <file>
  -p, --file <package> query a package file instead of the database
  -q, --quiet          show less information for query and search
  -r, --root <path>    set an alternate installation root
  -s, --search <regex> search locally-installed packages for matching strings
  -t, --unrequired     list packages not (optionally) required by any
                       package (-tt to ignore optdepends) [filter]
  -u, --upgrades       list outdated packages [filter]
  -v, --verbose        be verbose
      --arch <arch>    set an alternate architecture
      --cachedir <dir> set an alternate package cache location
      --color <when>   colorize the output
      --config <path>  set an alternate configuration file
      --confirm        always ask for confirmation
      --debug          display debug messages
      --disable-download-timeout
                       use relaxed timeouts for download
      --disable-sandbox
                       disables all sandbox features used for the downloader process
      --disable-sandbox-filesystem
                       disables the filesystem part of the downloader process sandbox
      --disable-sandbox-syscalls
                       disables the syscalls part of the downloader process sandbox
      --gpgdir <path>  set an alternate home directory for GnuPG
      --hookdir <dir>  set an alternate hook location
      --logfile <path> set an alternate log file
      --noconfirm      do not ask for any confirmation
      --sysroot        operate on a mounted guest system (root-only)

实测回显(列表样例,此时系统已装入演示包共 144 个):

$ pacman -Q | wc -l
144

$ pacman -Q | tail -6
tzdata 2026e-1
util-linux 2.42.4-1
util-linux-libs 2.42.4-1
xz 5.8.4-1
zlib 1:1.3.2-3
zstd 1.5.7-3

💡 要点:-Q 系参数几乎全是过滤器(-Q 帮助里标 [filter] 的那些),可以自由组合:-Qeq(显式安装、只打印包名)、-Qdq(以依赖身份安装的包名列表)、-Qm(不在软件源里的外来包,手工编译/-U 装的都会出现)。-Q 包名 指定名字时输出 包名 版本,名字不存在时报 error: package 'sl' was not found 并返回非零。

3.13 -Qs:本地搜索

-Qs 与 -Ss 同构,搜索范围换成已安装的包:

pacman -Qs tree
pacman -Qs '^htop$'

实测回显:

$ pacman -Qs tree
local/tree 2.3.2-1
    A directory listing program displaying a depth indented list of files

$ pacman -Qs '^htop$'
exit=1

第二条无输出、退出码 1(htop 在 3.10 节已被移除),匹配为空。

💡 要点:本地结果前缀是 local/,软件源结果前缀是仓库名(extra/)——这是快速区分"装没装"的视觉标记。pacman -Qs 关键字 匹配包名与描述;要精确按名字过滤用 ^名字$ 锚点。

3.14 -Qi:已安装包详细信息

pacman -Qi tree

实测回显:

$ pacman -Qi tree
Name            : tree
Version         : 2.3.2-1
Description     : A directory listing program displaying a depth indented list of files
Architecture    : x86_64
URL             : https://gitlab.com/OldManProgrammer/unix-tree
Licenses        : GPL-2.0-or-later
Groups          : None
Provides        : None
Depends On      : glibc
Optional Deps   : None
Required By     : None
Optional For    : None
Conflicts With  : None
Replaces        : None
Installed Size  : 94.00 KiB
Packager        : Jelle van der Waa <jelle@archlinux.org>
Build Date      : Sun Mar 29 14:23:02 2026
Install Date    : Fri Oct 16 16:26:16 2026
Install Reason  : Explicitly installed
Install Script  : No
Validated By    : Signature

💡 要点:与 -Si(3.7 节)对比,-Qi 多了三个本地字段:Install Date(安装时间)、Install Reason(Explicitly installed 显式 / Installed as a dependency for another package 依赖)、Install Script(是否执行过安装脚本)。Required By 显示本地真实反向依赖。-Qii 还会列出带 NEVRA 的备份文件与修改状态。

3.15 -Ql:列出包安装的文件清单

pacman -Ql tree
pacman -Ql tree | wc -l

实测回显:

$ pacman -Ql tree
tree /usr/
tree /usr/bin/
tree /usr/bin/tree
tree /usr/share/
tree /usr/share/man/
tree /usr/share/man/man1/
tree /usr/share/man/man1/tree.1.gz

$ pacman -Ql tree | wc -l
7

💡 要点:每行前缀是包名 + 空格 + 文件路径,目录条目以 / 结尾——这 7 行就是 tree 包在系统里留下的全部痕迹(pacman -Ql 包名 | grep -v '/$' 即纯文件列表)。查包"把什么文件放到了哪里"、排障时确认某二进制/配置属于哪个包,都靠它。

3.16 -Qo:反查文件属主

-Qo 是 -Ql 的逆操作:给定磁盘上的文件,查它属于哪个已安装包:

pacman -Qo /usr/bin/tree
pacman -Qo /usr/bin/htop
pacman -Qo /etc/os-release
pacman -Qo /root/not-owned-demo.txt

实测回显:

$ pacman -Qo /usr/bin/tree
/usr/bin/tree is owned by tree 2.3.2-1

$ pacman -Qo /usr/bin/htop
/usr/bin/htop is owned by htop 3.5.3-1

$ pacman -Qo /etc/os-release
error: No package owns /etc/os-release

$ pacman -Qo /root/not-owned-demo.txt
error: No package owns /root/not-owned-demo.txt
exit=1

💡 要点:报 error: No package owns ... 的两种真实成因:文件是手工创建的(如测试文件 not-owned-demo.txt),或文件由系统工具生成、不在任何包的文件清单里(本环境的 /etc/os-release 是生成文件,包里登记的对应物是 /usr/lib/os-release)。排障时它回答"这个二进制/配置是包管的还是有人手工改的":有属主 → 用包管理器恢复;无属主 → 人工接管。查"还没装的命令来自哪个包"用 -F(3.19 节)。

3.17 -Qe / -Qdt:显式安装列表与孤儿包

-Qe 列出显式安装的包(人为 pacman -S 装的);-Qdt 列出孤儿包(以依赖身份安装、现在没有任何包需要它们)。实测:

pacman -Qe
pacman -Qdt

实测回显(figlet 此前以 --asdeps 方式安装,即"依赖身份",所以出现在孤儿列表):

$ pacman -Qe
base 3-3
cowsay 3.8.4-1
htop 3.5.3-1
sl 5.05-6
tree 2.3.2-1

$ pacman -Qdt
figlet 2.2.5-6
exit=0

对照可见 figlet 不在 -Qe(非显式)却在 -Qdt(依赖身份且无人需要)——这正是"孤儿"的定义。安装原因标记不是死的:用 -D --asdeps/--asexplicit 改标记后 -Qdt 会随之增减(3.21 节以 tree 实测了完整的标记切换);figlet 的清理见 4.2 节。演示包全部收尾后 -Qdt 回归空(退出码 1 表示空列表):

$ pacman -Qdt
qdt_exit=1

💡 要点:-Qdt 是 Arch 日常维护的核心体检项:孤儿列表非空 = 有"只为别人而装、现在白占磁盘"的包。标准清理动作是 pacman -Rns $(pacman -Qdtq)(-Qdtq 的 q 只输出包名,列表为空时加 || true 防止空参数报错,见 4.2 节实战)。注意 -Qdt 只认 -t(unrequired)+-d(deps)两个条件的交集:被别的包可选依赖着的包不算孤儿(可用 -Qdtt 忽略可选依赖,即帮助里的 -tt)。

3.18 -Qu:列出可升级的包

-Qu 对照本地库与软件源库,列出有新版本的已安装包,只看不升。实测(升级前有 5 个可升级包):

pacman -Qu

实测回显:

$ pacman -Qu
curl 8.22.0-1 -> 8.23.0-1
libarchive 3.8.9-1 -> 3.8.10-1
pacman 7.1.0.r9.g54d9411-2 -> 7.1.0.r9.g54d9411-3
sqlite 3.53.4-1 -> 3.54.0-1
zlib 1:1.3.2-3 -> 1:1.3.2-4
exit=0

3.5 节 -Syu 执行后再测,列表为空、退出码 1:

$ pacman -Qu
qu_exit=1

💡 要点:-Qu 退出码语义:有可升级包 → 输出列表、退出 0;无可升级 → 无输出、退出 1。这让它能直接当监控探针:pacman -Qu | wc -l 给巡检脚本数"落后多少个包"。它是 -Q 过滤器(帮助里 [filter]),所以也有 -Quq 纯包名形态。查更新而完全不动本地库的另一个工具是 checkupdates(pacman-contrib 提供,见 FAQ Q10)。

3.19 -F 家族:文件数据库查询(-Fy/-F/-Fx/-Fl)

-F 回答"某个文件由哪个包提供",且不要求该包已安装——它查的是独立的"文件数据库",需要先 -Fy 下载。先看 -F --help 全量:

pacman -F --help
pacman -Fy
pacman -F 'usr/bin/tree'
pacman -F 'tree'
pacman -Fx '/usr/bin/zstd$'
pacman -Fl extra/tree | head -5

实测回显(-F --help 全量):

$ pacman -F --help
usage:  pacman {-F --files} [options] [file(s)]
options:
  -b, --dbpath <path>  set an alternate database location
  -l, --list           list the files owned by the queried package
  -q, --quiet          show less information for query and search
  -r, --root <path>    set an alternate installation root
  -v, --verbose        be verbose
  -x, --regex          enable searching using regular expressions
  -y, --refresh        download fresh package databases from the server
                       (-yy to force a refresh even if up to date)
      --arch <arch>    set an alternate architecture
      --cachedir <dir> set an alternate package cache location
      --color <when>   colorize the output
      --config <path>  set an alternate configuration file
      --confirm        always ask for confirmation
      --debug          display debug messages
      --disable-download-timeout
                       use relaxed timeouts for download
      --disable-sandbox
                       disables all sandbox features used for the downloader process
      --disable-sandbox-filesystem
                       disables the filesystem part of the downloader process sandbox
      --disable-sandbox-syscalls
                       disables the syscalls part of the downloader process sandbox
      --gpgdir <path>  set an alternate home directory for GnuPG
      --hookdir <dir>  set an alternate hook location
      --logfile <path> set an alternate log file
      --machinereadable
                       produce machine-readable output
      --noconfirm      do not ask for any confirmation
      --sysroot        operate on a mounted guest system (root-only)

实测回显(刷新与查询):

$ pacman -Fy
:: Synchronizing package databases...
 core downloading...
 extra downloading...
exit=0

$ pacman -F 'usr/bin/tree'
usr/bin/tree is owned by extra/tree 2.3.2-1

$ pacman -F 'tree'
extra/gstreamer-docs 1.28.8-1
    usr/share/doc/gstreamer/html/assets/js/search/tree
extra/smolvm 1.28.1-1
    usr/lib/smolvm/agent-rootfs/usr/bin/tree
extra/sugar-activity-pippy 76-1 (sugar-fructose)
    usr/share/sugar/activities/Pippy.activity/data/en/graphics/tree
extra/tree 2.3.2-1 [installed]
    usr/bin/tree
exit=0

$ pacman -Fx '/usr/bin/zstd$'
usr/bin/zstd is owned by core/zstd 1.5.7-3

$ pacman -Fl extra/tree | head -5
tree usr/
tree usr/bin/
tree usr/bin/tree
tree usr/share/
tree usr/share/man/

💡 要点:

  1. -F 的匹配对象是路径:写 usr/bin/tree 精确命中;只写 tree 会把路径任意位置含 tree 的全列出来(如文档目录里的 search/tree),命中项带 [installed] 标注是否已安装。
  2. -Fx 开正则($ 锚定结尾防误命中),-Fl 仓库/包名 反向列出仓库中某包的文件清单(对比 3.15 节 -Ql 只能看已装的),-Fy 与 -Sy 独立:文件库单独刷新、单独存储。
  3. 典型场景:"服务器上缺 xxx 命令,不知道装哪个包" → pacman -Fy && pacman -F xxx 一秒定位,这是 apt 的 apt-file、dnf 的 dnf provides 在 Arch 上的对应物。

3.20 -U:安装本地包文件 / URL

-U 绕过软件源解析,直接安装本地包文件或 URL 指向的包文件。演示素材正好有 3.8 节 -Sw 下载的 htop 缓存文件:

pacman -U --noconfirm /var/cache/pacman/pkg/htop-3.5.3-1-x86_64.pkg.tar.zst
htop --version | head -1

实测回显:

$ pacman -U --noconfirm /var/cache/pacman/pkg/htop-3.5.3-1-x86_64.pkg.tar.zst
loading packages...
resolving dependencies...
looking for conflicting packages...

Package (1)  New Version  Net Change

htop         3.5.3-1        0.41 MiB

Total Installed Size:  0.41 MiB

:: Proceed with installation? [Y/n]
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
:: Processing package changes...
installing htop...
Optional dependencies for htop
    lm_sensors: show cpu temperatures
    lsof: show files opened by a process
    strace: attach to a running process
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
exit=0

$ htop --version | head -1
htop 3.5.3-1-arch

移除 sl 后从缓存文件重装(不访问网络),再从软件源 URL 直接重装:

pacman -R --noconfirm sl
f=$(ls /var/cache/pacman/pkg/ | grep '^sl-.*\.pkg\.tar\.zst$' | head -1)
echo "file: $f"
pacman -U --noconfirm "/var/cache/pacman/pkg/$f"
pacman -Q sl
pacman -U --noconfirm "https://geo.mirror.pkgbuild.com/extra/os/x86_64/$f"
pacman -Q sl

实测回显:

$ pacman -R --noconfirm sl
checking dependencies...

Package (1)  Old Version  Net Change

sl           5.05-6        -0.03 MiB

Total Removed Size:  0.03 MiB

:: Do you want to remove these packages? [Y/n]
:: Processing package changes...
removing sl...
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
exit=0

$ f=$(ls /var/cache/pacman/pkg/ | grep '^sl-.*\.pkg\.tar\.zst$' | head -1)
$ echo "file: $f"
file: sl-5.05-6-x86_64.pkg.tar.zst

$ pacman -U --noconfirm "/var/cache/pacman/pkg/$f"
loading packages...
resolving dependencies...
looking for conflicting packages...

Package (1)  New Version  Net Change

sl           5.05-6         0.03 MiB

Total Installed Size:  0.03 MiB

:: Proceed with installation? [Y/n]
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
:: Processing package changes...
installing sl...
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
exit=0

$ pacman -Q sl
sl 5.05-6

$ pacman -U --noconfirm "https://geo.mirror.pkgbuild.com/extra/os/x86_64/$f"
warning: sl-5.05-6 is up to date -- reinstalling
loading packages...
resolving dependencies...
looking for conflicting packages...

Package (1)  Old Version  New Version  Net Change

sl           5.05-6       5.05-6         0.00 MiB

Total Installed Size:  0.03 MiB
Net Upgrade Size:      0.00 MiB

:: Proceed with installation? [Y/n]
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
:: Processing package changes...
reinstalling sl...
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
exit=0

$ pacman -Q sl
sl 5.05-6

💡 要点:

  1. -U 的输出以 loading packages... 开头(-S 是 resolving dependencies... 起手),本地文件安装同样走 keyring/完整性校验;URL 形态会先下载到缓存再走同一流程,-U 装的包在 -Qm(外来包过滤器)里能查到吗——能,只要它不在任何同步仓库里。
  2. 依赖仍会解析:本地文件若缺依赖,pacman 会尝试从软件源补齐;完全离线装包用 -Ud(跳过依赖检查)或把依赖包一并 -U 传入。
  3. -U 也支持 --needed(同版本跳过)与目录参数(pacman -U /path/to/dir/ 批量装目录下所有包文件)。降级场景(rolling 系统回滚某个包)就是 -U 旧版本包文件的天下,配合 Archive 归档源(archive.archlinux.org)使用。

3.21 -D:数据库操作(--asdeps / --asexplicit / -Dk)

-D 直接修改本地数据库的元信息,不触碰包文件。三个高频用法:改安装原因标记、检查数据库完整性。先看 -D --help 全量:

pacman -D --help
pacman -D --asdeps tree
pacman -Qi tree | grep 'Install Reason'
pacman -Qdt
pacman -D --asexplicit tree
pacman -Qi tree | grep 'Install Reason'
pacman -Dk

实测回显(-D --help 全量):

$ pacman -D --help
usage:  pacman {-D --database} <options> <package(s)>
options:
  -b, --dbpath <path>  set an alternate database location
  -k, --check          test local database for validity (-kk for test sync databases)
  -q, --quiet          suppress output of success messages
  -r, --root <path>    set an alternate installation root
  -v, --verbose        be verbose
      --arch <arch>    set an alternate architecture
      --asdeps         mark packages as non-explicitly installed
      --asexplicit     mark packages as explicitly installed
      --cachedir <dir> set an alternate package cache location
      --color <when>   colorize the output
      --config <path>  set an alternate configuration file
      --confirm        always ask for confirmation
      --debug          display debug messages
      --disable-download-timeout
                       use relaxed timeouts for download
      --disable-sandbox
                       disables all sandbox features used for the downloader process
      --disable-sandbox-filesystem
                       disables the filesystem part of the downloader process sandbox
      --disable-sandbox-syscalls
                       disables the syscalls part of the downloader process sandbox
      --gpgdir <path>  set an alternate home directory for GnuPG
      --hookdir <dir>  set an alternate hook location
      --logfile <path> set an alternate log file
      --noconfirm      do not ask for any confirmation
      --sysroot        operate on a mounted guest system (root-only)

实测回显(标记切换与数据库检查):

$ pacman -D --asdeps tree
tree: install reason has been set to 'installed as dependency'
exit=0

$ pacman -Qi tree | grep 'Install Reason'
Install Reason  : Installed as a dependency for another package

$ pacman -Qdt
figlet 2.2.5-6
tree 2.3.2-1

$ pacman -D --asexplicit tree
tree: install reason has been set to 'explicitly installed'
exit=0

$ pacman -Qi tree | grep 'Install Reason'
Install Reason  : Explicitly installed

$ pacman -Qdt
figlet 2.2.5-6
qdt_exit=0

$ pacman -Dk
No database errors have been found!
exit=0

💡 要点:

  1. --asdeps/--asexplicit 决定包在孤儿分析(-Qdt)里的身份:tree 被标成"依赖"后立刻出现在 -Qdt,标回"显式"后从列表消失(上面只剩 figlet,它是"从未被标显式"的真孤儿,4.2 节清理)。实战价值:手工补装了某服务的依赖库时用 --asdeps 标记,避免它被 -Rns $(pacman -Qdtq) 误留或误删;"这个包我就是要长期留着"用 --asexplicit 免疫孤儿清理。
  2. 安装时就指定身份的写法是 pacman -S --asdeps 包名(figlet 即此方式装入,3.1/3.17 节),事后补标记用 -D。
  3. -Dk 对本地库做一致性体检(缺依赖、缺文件记录都会报错非零),3.11 节强移 perl 后它如实报了 missing 'perl' dependency for 'cowsay';-Dkk 连软件源库一起查。定期巡检可加入 -Dk。

3.22 -T:依赖检查(不执行变更)

-T(deptest)检查给定"依赖描述"是否已满足:满足输出空、退出 0;不满足打印缺失项、退出 127。它不改系统,专门给脚本做预检:

pacman -T bash tree
echo "exit=$?"
pacman -T neofetch
echo "exit=$?"
pacman -T 'bash>1'
echo "exit=$?"
pacman -T 'bash>999.9'
echo "exit=$?"
pacman -T bash neofetch
echo "exit=$?"

实测回显:

$ pacman -T bash tree
exit=0

$ pacman -T neofetch
neofetch
exit=127

$ pacman -T 'bash>1'
exit=0

$ pacman -T 'bash>999.9'
bash>999.9
exit=127

$ pacman -T bash neofetch
neofetch
exit=127

💡 要点:

  1. -T 支持依赖描述的完整语法:包名、包名>版本、包名>=版本、包名=版本。注意版本比较走 vercmp 语义(逐段数字比较):本机 bash 是 5.3.x,bash>999.9 判为不满足(因为版本段比较时 999 > 5),bash>1 满足——写版本约束前拿 pacman -T 试一下最稳。
  2. 多个依赖混合时"一个缺失即整体不满足",且只打印缺失的那几个(上例只打印 neofetch,bash 满足不打印)。
  3. 经典用法:脚本里 if [ -z "$(pacman -T git curl)" ]; then echo "依赖齐全"; fi,或者"缺什么装什么":missing=$(pacman -T git curl) && [ -n "$missing" ] && pacman -S --needed --noconfirm $missing。

3.23 -b/--dbpath 与 --cachedir:替代数据库与缓存路径

-b/--dbpath 指定数据库(已装包记录 + 软件源库)的替代位置;--cachedir 指定包文件缓存的替代位置。两者都要求目标目录预先存在,否则直接报错——这是实测踩到的第一个坑:

pacman -Sw --noconfirm --cachedir /var/tmp/pkgcache figlet

实测回显(目录不存在时):

$ pacman -Sw --noconfirm --cachedir /var/tmp/pkgcache figlet
error: 'failed to resolve path '/var/tmp/pkgcache' passed to '--cachedir': No such file or directory
exit=1

创建目录后重试,成功下载到替代缓存:

mkdir -p /var/tmp/pkgcache
pacman -Sw --noconfirm --cachedir /var/tmp/pkgcache figlet
ls -l /var/tmp/pkgcache/ | grep figlet

实测回显:

$ mkdir -p /var/tmp/pkgcache

$ pacman -Sw --noconfirm --cachedir /var/tmp/pkgcache figlet
resolving dependencies...

Package (1)   New Version  Net Change  Download Size

extra/figlet  2.2.5-6        0.63 MiB       0.10 MiB

Total Download Size:  0.10 MiB

:: Proceed with download? [Y/n]
:: Retrieving packages...
 figlet-2.2.5-6-x86_64 downloading...
checking keyring...
checking package integrity...
exit=0

$ ls -l /var/tmp/pkgcache/ | grep figlet
-rw-r--r-- 1 root root 105163 Jul 12  2024 figlet-2.2.5-6-x86_64.pkg.tar.zst
-rw-r--r-- 1 root root    119 Jul 12  2024 figlet-2.2.5-6-x86_64.pkg.tar.zst.sig

-b 把整套数据库刷到独立目录(不碰 /var/lib/pacman),适合离线救援分析、测试数据库操作:

mkdir -p /var/tmp/altdb
pacman -Sy -b /var/tmp/altdb
find /var/tmp/altdb -type f | sort

实测回显:

$ mkdir -p /var/tmp/altdb

$ pacman -Sy -b /var/tmp/altdb
:: Synchronizing package databases...
 core downloading...
 extra downloading...
exit=0

$ find /var/tmp/altdb -type f | sort
/var/tmp/altdb/local/ALPM_DB_VERSION
/var/tmp/altdb/sync/core.db
/var/tmp/altdb/sync/extra.db

💡 要点:

  1. 目录不存在时两个参数报同构错误:failed to resolve path ... passed to '--cachedir'/'--dbpath': No such file or directory,退出码 1——先 mkdir -p 再执行。
  2. -b /var/tmp/altdb 后的 -Sy 在新位置生成 local/(本地库)与 sync/(软件源库)完整结构;--cachedir 只影响包文件(.pkg.tar.zst)落点,两者职责不同:-b 管"记录",--cachedir 管"文件"。
  3. 典型用途:给系统盘做救援分析时 -b 指向挂载的目标盘数据库;多机离线分发时 --cachedir 指向共享目录,一次下载处处安装。

3.24 -Sc / -Scc:清理包缓存

-Sc 清理缓存中"已卸载包"的包文件(保留已安装包的);-Scc 清空全部。实测前先看缓存现状(34 个文件,含已卸载的 sl/figlet/htop/cowsay/perl/db5.3 的包文件):

ls /var/cache/pacman/pkg/ | wc -l
pacman -Sc --noconfirm
ls /var/cache/pacman/pkg/

实测回显:

$ ls /var/cache/pacman/pkg/ | wc -l
34

$ pacman -Sc --noconfirm
Packages to keep:
  All locally installed packages

Cache directory: /var/cache/pacman/pkg/
:: Do you want to remove all other packages from cache? [Y/n] error: could not open file /var/cache/pacman/pkg/download-XXAg8J: Error reading fd 8
error: could not open file /var/cache/pacman/pkg/download-zqV9KF: Error reading fd 8
error: could not open file /var/cache/pacman/pkg/download-qx6Ol6: Error reading fd 8
error: could not open file /var/cache/pacman/pkg/download-xtqsFn: Error reading fd 8
error: could not open file /var/cache/pacman/pkg/download-JT4aia: Error reading fd 8
error: could not open file /var/cache/pacman/pkg/download-VgmV6v: Error reading fd 8
error: could not open file /var/cache/pacman/pkg/download-9VdwlW: Error reading fd 8
error: could not open file /var/cache/pacman/pkg/download-86psjV: Error reading fd 8

removing old packages from cache...

Database directory: /var/lib/pacman/
:: Do you want to remove unused repositories? [Y/n]
removing unused sync repositories...
exit=0

$ ls /var/cache/pacman/pkg/
archlinux-keyring-20260909-1-any.pkg.tar.zst
archlinux-keyring-20260909-1-any.pkg.tar.zst.sig
curl-8.23.0-1-x86_64.pkg.tar.zst
curl-8.23.0-1-x86_64.pkg.tar.zst.sig
download-86psjV
download-9VdwlW
download-JT4aia
download-VgmV6v
download-XXAg8J
download-qx6Ol6
download-xtqsFn
download-zqV9KF
libarchive-3.8.10-1-x86_64.pkg.tar.zst
libarchive-3.8.10-1-x86_64.pkg.tar.zst.sig
pacman-7.1.0.r9.g54d9411-3-x86_64.pkg.tar.zst
pacman-7.1.0.r9.g54d9411-3-x86_64.pkg.tar.zst.sig
sqlite-3.54.0-1-x86_64.pkg.tar.zst
sqlite-3.54.0-1-x86_64.pkg.tar.zst.sig
tree-2.3.2-1-x86_64.pkg.tar.zst
tree-2.3.2-1-x86_64.pkg.tar.zst.sig
zlib-1:1.3.2-4-x86_64.pkg.tar.zst
zlib-1:1.3.2-4-x86_64.pkg.tar.zst.sig

-Scc --noconfirm 的真实结果(注意:缓存没有被清空):

pacman -Scc --noconfirm
echo "exit=$?"
ls -A /var/cache/pacman/pkg/

实测回显:

$ pacman -Scc --noconfirm

Cache directory: /var/cache/pacman/pkg/
:: Do you want to remove ALL files from cache? [y/N]

Database directory: /var/lib/pacman/
:: Do you want to remove unused repositories? [Y/n]
removing unused sync repositories...
exit=0
total 6788
-rw-r--r-- 1 root root 1273532 Sep  9 07:47 archlinux-keyring-20260909-1-any.pkg.tar.zst
-rw-r--r-- 1 root root     119 Sep  9 07:47 archlinux-keyring-20260909-1-any.pkg.tar.zst.sig
-rw-r--r-- 1 root root 1372375 Oct 14 08:43 curl-8.23.0-1-x86_64.pkg.tar.zst
-rw-r--r-- 1 root root     119 Oct 14 08:43 curl-8.23.0-1-x86_64.pkg.tar.zst.sig
drwx------ 2 alpm alpm    4096 Oct 16 16:28 download-86psjV
drwx------ 2 alpm alpm    4096 Oct 16 16:26 download-9VdwlW
drwx------ 2 alpm alpm    4096 Oct 16 16:31 download-JT4aia
drwx------ 2 alpm alpm    4096 Oct 16 16:30 download-VgmV6v
drwx------ 2 alpm alpm    4096 Oct 16 16:25 download-XXAg8J
drwx------ 2 alpm alpm    4096 Oct 16 16:28 download-qx6Ol6
drwx------ 2 alpm alpm    4096 Oct 16 16:28 download-xtqsFn
drwx------ 2 alpm alpm    4096 Oct 16 16:28 download-zqV9KF
-rw-r--r-- 1 root root  602031 Oct 14 13:58 libarchive-3.8.10-1-x86_64.pkg.tar.zst
-rw-r--r-- 1 root root     119 Oct 14 13:58 libarchive-3.8.10-1-x86_64.pkg.tar.zst.sig
-rw-r--r-- 1 root root  993348 Oct 15 08:29 pacman-7.1.0.r9.g54d9411-3-x86_64.pkg.tar.zst
-rw-r--r-- 1 root root     119 Oct 15 08:29 pacman-7.1.0.r9.g54d9411-3-x86_64.pkg.tar.zst.sig
-rw-r--r-- 1 root root 2505466 Oct  9 21:08 sqlite-3.54.0-1-x86_64.pkg.tar.zst
-rw-r--r-- 1 root root     310 Oct  9 21:08 sqlite-3.54.0-1-x86_64.pkg.tar.zst.sig
-rw-r--r-- 1 root root   44562 Mar 29  2026 tree-2.3.2-1-x86_64.pkg.tar.zst
-rw-r--r-- 1 root root     310 Mar 29  2026 tree-2.3.2-1-x86_64.pkg.tar.zst.sig
-rw-r--r-- 1 root root   86278 Oct 12 12:28 zlib-1:1.3.2-4-x86_64.pkg.tar.zst
-rw-r--r-- 1 root root     119 Oct 12 12:28 zlib-1:1.3.2-4-x86_64.pkg.tar.zst.sig

确认问题需要显式 y 才真正清空(管道注入),同时清理 pacman 7.x 下载器遗留的 download-* 临时目录:

yes | pacman -Scc
rm -rf /var/cache/pacman/pkg/download-*
ls -A /var/cache/pacman/pkg/

实测回显:

$ yes | pacman -Scc

Cache directory: /var/cache/pacman/pkg/
:: Do you want to remove ALL files from cache? [y/N] y
error: could not remove /var/cache/pacman/pkg/download-XXAg8J: Is a directory
error: could not remove /var/cache/pacman/pkg/download-zqV9KF: Is a directory
error: could not remove /var/cache/pacman/pkg/download-qx6Ol6: Is a directory
error: could not remove /var/cache/pacman/pkg/download-xtqsFn: Error reading fd 8
error: could not remove /var/cache/pacman/pkg/download-JT4aia: Is a directory
error: could not remove /var/cache/pacman/pkg/download-VgmV6v: Is a directory
error: could not remove /var/cache/pacman/pkg/download-9VdwlW: Is a directory
removing all files from cache...

Database directory: /var/lib/pacman/
error: could not remove /var/cache/pacman/pkg/download-86psjV: Is a directory
:: Do you want to remove unused repositories? [Y/n] y
removing unused sync repositories...
exit=248

$ rm -rf /var/cache/pacman/pkg/download-*

$ ls -A /var/cache/pacman/pkg/
ls_exit=0

💡 要点:

  1. ⚠️ 实测踩坑一:-Scc --noconfirm 不会清空缓存。原因在 3.2 节埋过伏笔:--noconfirm 按方括号默认值应答,而"remove ALL files"问句写的是 [y/N]——默认 N,于是跳过。要无人值守清空只能显式应答:yes | pacman -Scc。
  2. 实测踩坑二:pacman 7.x 下载器(沙箱用户 alpm)会在缓存目录留下 download-* 临时目录,-Sc/-Scc 都处理不了(报 Is a directory/Error reading fd 8),需要手工 rm -rf /var/cache/pacman/pkg/download-*。
  3. 分级建议:日常 -Sc(保留已装包的缓存,可离线重装/降级);磁盘紧张才 -Scc(连已装包的缓存一起删,之后重装必须联网);更精细的"保留最近 N 个版本"用 pacman-contrib 的 paccache -rk1。

3.25 pacman.conf 核心配置项实测

/etc/pacman.conf 分 [options] 全局段与仓库段([core]/[extra],各自 Include = /etc/pacman.d/mirrorlist)。有效配置行已在 2.3 节全量展示,本节实测三个高频键。先测 IgnorePkg(锁定版本,-Syu 跳过升级;直接安装时二次确认)——把 tree 写入 IgnorePkg 后尝试安装:

cp /etc/pacman.conf /etc/pacman.conf.good
sed -i 's/^#IgnorePkg   =/IgnorePkg   = tree/' /etc/pacman.conf
grep -n '^IgnorePkg' /etc/pacman.conf
printf 'n\n' | pacman -S tree
mv /etc/pacman.conf.good /etc/pacman.conf
grep -c '^IgnorePkg' /etc/pacman.conf

实测回显:

$ cp /etc/pacman.conf /etc/pacman.conf.good

$ sed -i 's/^#IgnorePkg   =/IgnorePkg   = tree/' /etc/pacman.conf

$ grep -n '^IgnorePkg' /etc/pacman.conf
25:IgnorePkg   = tree

$ printf 'n\n' | pacman -S tree
:: tree is in IgnorePkg/IgnoreGroup. Install anyway? [Y/n] n
warning: skipping target: tree
 there is nothing to do
exit=0

$ mv /etc/pacman.conf.good /etc/pacman.conf

$ grep -c '^IgnorePkg' /etc/pacman.conf
0

再测 HoldPkg(禁删名单,默认已含 pacman glibc)——把 tree 临时加入后尝试移除:

cp /etc/pacman.conf /etc/pacman.conf.good
sed -i 's/^HoldPkg     = pacman glibc/HoldPkg     = pacman glibc tree/' /etc/pacman.conf
grep -n '^HoldPkg' /etc/pacman.conf
pacman -R --noconfirm tree
mv /etc/pacman.conf.good /etc/pacman.conf
pacman -Q tree

实测回显:

$ cp /etc/pacman.conf /etc/pacman.conf.good

$ sed -i 's/^HoldPkg     = pacman glibc/HoldPkg     = pacman glibc tree/' /etc/pacman.conf

$ grep -n '^HoldPkg' /etc/pacman.conf
18:HoldPkg     = pacman glibc tree

$ pacman -R --noconfirm tree
checking dependencies...
:: HoldPkg was found in target list. Do you want to continue? [y/N] warning: tree is designated as a HoldPkg.

exit=1

$ mv /etc/pacman.conf.good /etc/pacman.conf

$ pacman -Q tree
tree 2.3.2-1

最后测 ParallelDownloads(并发下载连接数,默认 5)——改为 1 后下载 htop:

sed -i 's/^ParallelDownloads = 5/ParallelDownloads = 1/' /etc/pacman.conf
grep -n '^ParallelDownloads' /etc/pacman.conf
pacman -Sw --noconfirm htop
sed -i 's/^ParallelDownloads = 1/ParallelDownloads = 5/' /etc/pacman.conf
grep -n '^ParallelDownloads' /etc/pacman.conf

实测回显:

$ sed -i 's/^ParallelDownloads = 5/ParallelDownloads = 1/' /etc/pacman.conf

$ grep -n '^ParallelDownloads' /etc/pacman.conf
38:ParallelDownloads = 1

$ pacman -Sw --noconfirm htop
resolving dependencies...

Package (1)  New Version  Net Change  Download Size

extra/htop   3.5.3-1        0.41 MiB       0.18 MiB

Total Download Size:  0.18 MiB

:: Proceed with download? [Y/n]
:: Retrieving packages...
 htop-3.5.3-1-x86_64 downloading...
checking keyring...
checking package integrity...

$ sed -i 's/^ParallelDownloads = 1/ParallelDownloads = 5/' /etc/pacman.conf

$ grep -n '^ParallelDownloads' /etc/pacman.conf
38:ParallelDownloads = 5

💡 要点:

  1. IgnorePkg:-Syu 对名单内包打 warning: xxx: ignoring package upgrade 跳过升级;即使显式 pacman -S 包名 也会二次确认(实测 :: tree is in IgnorePkg/IgnoreGroup. Install anyway? [Y/n]),答 n 则 warning: skipping target: tree。滚动系统上"个别包暂不升级"(如等待上游兼容)就靠它,恢复后删除该行即可。
  2. HoldPkg:移除名单内包时触发 :: HoldPkg was found in target list. Do you want to continue? [y/N],非交互(EOF)直接中止(退出码 1),tree 仍在(pacman -Q tree 可查)。默认名单里的 pacman/glibc 属于"删掉即残废"的核心包,勿动。
  3. ParallelDownloads:并发下载数,大包多包场景调大(5~10)明显提速;网络质量差时可降到 1 或配合 DisableDownloadTimeout(放宽下载超时)。
  4. 其余本机实测存在的键:NoProgressBar(不显示进度条)、VerbosePkgLists(事务摘要用宽表格式,即本文所有摘要表的来源)、DownloadUser = alpm(下载进程降权到专用用户,pacman 7 沙箱特性)、SigLevel = Required DatabaseOptional(包签名强制校验、数据库签名可选校验——3.27 节签名修复的配置基础)、LocalFileSigLevel = Optional(本地 -U 安装不强制验签)。

3.26 mirrorlist 软件源配置与排序

/etc/pacman.d/mirrorlist 是仓库段的 Server 清单,自上而下逐个尝试:前一个失败(超时/解析失败)自动换下一个。把两条 Server 全部替换成不可达的假源,实测 -Sy 的完整报错:

cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.good
sed -i 's|^Server = .*|Server = http://mirror-broken.invalid/$repo/os/$arch|' /etc/pacman.d/mirrorlist
cat /etc/pacman.d/mirrorlist
pacman -Sy
mv /etc/pacman.d/mirrorlist.good /etc/pacman.d/mirrorlist
pacman -Syy

实测回显:

$ cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.good

$ sed -i 's|^Server = .*|Server = http://mirror-broken.invalid/$repo/os/$arch|' /etc/pacman.d/mirrorlist

$ cat /etc/pacman.d/mirrorlist
Server = http://mirror-broken.invalid/$repo/os/$arch
Server = http://mirror-broken.invalid/$repo/os/$arch

$ pacman -Sy
:: Synchronizing package databases...
error: failed retrieving file 'core.db' from mirror-broken.invalid : Could not resolve host: mirror-broken.invalid
warning: fatal error from mirror-broken.invalid, skipping for the remainder of this transaction
error: failed retrieving file 'extra.db' from mirror-broken.invalid : Could not resolve host: mirror-broken.invalid
error: failed to synchronize all databases (failed to retrieve some files)
 core downloading...
 extra downloading...
exit=1

$ mv /etc/pacman.d/mirrorlist.good /etc/pacman.d/mirrorlist

$ pacman -Syy
:: Synchronizing package databases...
 core downloading...
 extra downloading...
exit=0

软件源排序:pacman 按文件顺序尝试,顺序本身由测速工具生成——pacman-contrib 提供的 rankmirrors 逐个测速并按耗时输出排序结果(本机 2 条源实测):

pacman -S --noconfirm pacman-contrib
rankmirrors -n 2 /etc/pacman.d/mirrorlist

实测回显:

$ pacman -S --noconfirm pacman-contrib
resolving dependencies...
looking for conflicting packages...

Package (1)           New Version  Net Change  Download Size

extra/pacman-contrib  1.13.1-1       0.13 MiB       0.05 MiB

Total Download Size:  0.05 MiB
Total Installed Size:  0.13 MiB

:: Proceed with installation? [Y/n]
:: Retrieving packages...
 pacman-contrib-1.13.1-1-x86_64 downloading...
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
:: Processing package changes...
installing pacman-contrib...
Optional dependencies for pacman-contrib
    diffutils: for pacdiff
    fakeroot: for checkupdates
    findutils: for pacdiff --find [installed]
    mlocate: for pacdiff --locate
    plocate: faster mlocate alternative
    perl: for pacsearch
    sudo: privilege elevation for several scripts
    vim: default diff program for pacdiff
    neovim: default diff program for pacdiff if EDITOR=nvim
:: Running post-transaction hooks...
(1/2) Reloading system manager configuration...
  Skipped: Current root is not booted.
(2/2) Arming ConditionNeedsUpdate...
exit=0

$ rankmirrors -n 2 /etc/pacman.d/mirrorlist
# Server list generated by rankmirrors on 2026-10-16
Server = https://fastly.mirror.pkgbuild.com/$repo/os/$arch
Server = https://geo.mirror.pkgbuild.com/$repo/os/$arch

💡 技术拓展:软件源测速排序不止 rankmirrors 一个工具,常见方案对比——

工具原理特点
rankmirrors逐个下载仓库库文件计时排序pacman-contrib 自带,输入现有 mirrorlist 输出排序结果(本文实测所用)
reflector拉取官方软件源站点状态列表,按速率/HTTPS/国家过滤并排序一条命令生成整份 mirrorlist,社区目前的主流推荐
手工置顶把可信/最快的 Server 行放最前零依赖,适合只缓存了几条源的场合
官方生成页archlinux.org/mirrorlist 按国家勾选生成免安装,结果还需自行测速

排序产物是同一格式:## Score 风格的耗时注释 + 按快到慢排列的 Server 行;pacman 只认行的先后顺序。本机源少(2 条),rankmirrors -n 2 直接复现了原顺序,说明 fastly 站点当前更快。

3.27 keyring 签名校验:报错复现与修复

pacman 默认 SigLevel = Required DatabaseOptional(3.25 节):每个包文件必须验签。签名信任链的根是 archlinux-keyring 包维护的密钥环 /etc/pacman.d/gnupg/。keyring 过旧或损坏(老系统久未升级、安装介质里自带的密钥环时间久远)时,所有安装都会倒在签名校验上。实测复现:备份并重置密钥环,用空 keyring 重装 tree:

mv /etc/pacman.d/gnupg /etc/pacman.d/gnupg.bak
pacman-key --init
pacman -S --noconfirm tree

实测回显(--init 生成空密钥环):

$ mv /etc/pacman.d/gnupg /etc/pacman.d/gnupg.bak

$ pacman-key --init
gpg: /etc/pacman.d/gnupg/trustdb.gpg: trustdb created
gpg: no ultimately trusted keys found
gpg: starting migration from earlier GnuPG versions
gpg: porting secret keys from '/etc/pacman.d/gnupg/secring.gpg' to gpg-agent
gpg: migration succeeded
==> Generating pacman master key. This may take some time.
gpg: Generating pacman keyring master key...
gpg: directory '/etc/pacman.d/gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/etc/pacman.d/gnupg/openpgp-revocs.d/95B412196694E1201A5EE6DA9CAEAAEEBAF8C308.rev'
gpg: Done
==> Updating trust database...
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
init_exit=0

实测回显(空 keyring 下安装,签名校验报错):

$ pacman -S --noconfirm tree
warning: tree-2.3.2-1 is up to date -- reinstalling
resolving dependencies...
looking for conflicting packages...

Package (1)  Old Version  New Version  Net Change

extra/tree   2.3.2-1      2.3.2-1        0.00 MiB

Total Installed Size:  0.09 MiB
Net Upgrade Size:      0.00 MiB

:: Proceed with installation? [Y/n]
checking keyring...
downloading required keys...
:: Import PGP key C06086337C50773E, "Jelle van der Waa <jelle@archlinux.org>"? [Y/n]
checking package integrity...
error: tree: signature from "Jelle van der Waa <jelle@archlinux.org>" is unknown trust
error: failed to commit transaction (invalid or corrupted package (PGP signature))
:: File /var/cache/pacman/pkg/tree-2.3.2-1-x86_64.pkg.tar.zst is corrupted (invalid or corrupted package (PGP signature)).
Do you want to delete it? [Y/n]
Errors occurred, no packages were upgraded.
install_exit=1

修复流程一(keyring 文件还在、只是过期):先升 keyring 包本身 pacman -Sy archlinux-keyring --noconfirm(实测同版本重装,其钩子自动 Appending keys from archlinux.gpg... 更新信任库):

pacman -Sy archlinux-keyring --noconfirm

实测回显:

$ pacman -Sy archlinux-keyring --noconfirm
:: Synchronizing package databases...
 core downloading...
 extra downloading...
warning: archlinux-keyring-20260909-1 is up to date -- reinstalling
resolving dependencies...
looking for conflicting packages...

Package (1)             Old Version  New Version  Net Change  Download Size

core/archlinux-keyring  20260909-1   20260909-1     0.00 MiB       1.21 MiB

Total Download Size:   1.21 MiB
Total Installed Size:  1.73 MiB
Net Upgrade Size:      0.00 MiB

:: Proceed with installation? [Y/n]
:: Retrieving packages...
 archlinux-keyring-20260909-1-any downloading...
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
:: Processing package changes...
reinstalling archlinux-keyring...
==> Appending keys from archlinux.gpg...
==> Updating trust database...
gpg: next trustdb check due at 2026-10-26
:: Running post-transaction hooks...
(1/3) Reloading system manager configuration...
  Skipped: Current root is not booted.
(2/3) Enqueuing marked services...
  Skipped: Current root is not booted.
(3/3) Arming ConditionNeedsUpdate...
exit=0

修复流程二(keyring 损坏/被清空,本例场景):pacman-key --populate 从本地 /usr/share/pacman/keyrings/ 重新灌入官方主密钥:

pacman-key --populate archlinux
pacman -S --noconfirm tree
rm -rf /etc/pacman.d/gnupg.bak

实测回显:

$ pacman-key --populate archlinux
==> Appending keys from archlinux.gpg...
==> Locally signing trusted keys in keyring...
  -> Locally signed 5 keys.
==> Importing owner trust values...
gpg: setting ownertrust to 4
gpg: setting ownertrust to 4
gpg: setting ownertrust to 4
gpg: inserting ownertrust of 4
gpg: setting ownertrust to 4
==> Disabling revoked keys in keyring...
  -> Disabled 38 keys.
==> Updating trust database...
gpg: Note: third-party key signatures using the SHA1 algorithm are rejected
gpg: (use option "--allow-weak-key-signatures" to override)
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   1  signed:   5  trust: 0-, 0q, 0n, 5m, 0f, 1u
gpg: depth: 1  valid:   5  signed:  89  trust: 0-, 0q, 0n, 5m, 0f, 0u
gpg: depth: 2  valid:  78  signed:  18  trust: 78-, 0q, 0n, 0m, 0f, 0u
gpg: next trustdb check due at 2026-10-26
populate_exit=0

$ pacman -S --noconfirm tree
warning: tree-2.3.2-1 is up to date -- reinstalling
resolving dependencies...
looking for conflicting packages...

Package (1)  Old Version  New Version  Net Change  Download Size

extra/tree   2.3.2-1      2.3.2-1        0.00 MiB       0.04 MiB

Total Download Size:   0.04 MiB
Total Installed Size:  0.09 MiB
Net Upgrade Size:      0.00 MiB

:: Proceed with installation? [Y/n]
:: Retrieving packages...
 tree-2.3.2-1-x86_64 downloading...
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
:: Processing package changes...
reinstalling tree...
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
retry_exit=0

💡 要点:

  1. 报错特征:error: xxx: signature from "打包者" is unknown trust → failed to commit transaction (invalid or corrupted package (PGP signature))。注意包文件本身没坏(还提示是否删除缓存文件),坏的是信任链——所以盲目 pacman -Scc 清缓存无效,方向应是修 keyring。
  2. 两条修复路径的适用顺序:keyring 只是旧 → pacman -Sy archlinux-keyring(通常此时旧 keyring 还能验过 keyring 包自身的签名);keyring 已损坏(本例空库)→ pacman-key --init && pacman-key --populate archlinux,populate 从磁盘上的 /usr/share/pacman/keyrings/archlinux.gpg 离线重建信任链(Locally signed 5 keys / Disabled 38 keys),不依赖网络。日常保平安:把 archlinux-keyring 放进定期 -Syu 的白名单,别把它锁进 IgnorePkg。
  3. pacman-key --list-keys 可查看当前信任的密钥(重建后首行即本机生成的 pacman master key);报错里的 C06086337C50773E 与 3.7 节 -Sii 的 Signatures 字段一致,形成闭环。

3.28 拓展:主流包管理器常用操作对照

pacman 的操作模型放到其他发行版同样成立,下表按"同一件事"横向对照(本文 pacman 列全部实测,其余列为通用等价命令):

操作pacman (Arch)apt/dpkg (Debian/Ubuntu)yum (CentOS 7)dnf (Fedora/RHEL 8+)zypper (openSUSE)apk (Alpine)emerge (Gentoo)xbps (Void)
刷新软件源索引pacman -Syapt updateyum makecachednf makecachezypper refreshapk updateemerge --syncxbps-install -S
安装包pacman -S pkgapt install pkgyum install pkgdnf install pkgzypper install pkgapk add pkgemerge pkgxbps-install pkg
全系统升级pacman -Syuapt upgrade / apt full-upgradeyum updatednf upgradezypper update / zypper dupapk upgradeemerge -uDN @worldxbps-install -Su
搜索包pacman -Ss kwapt search kwyum search kwdnf search kwzypper search kwapk search kwemerge -s kwxbps-query -Rs kw
查看包信息pacman -Si pkgapt show pkgyum info pkgdnf info pkgzypper info pkgapk info pkgemerge --info pkgxbps-query -R pkg
已安装列表pacman -Qdpkg -lyum list installeddnf list installedzypper search -iapk infoqlist -Ixbps-query -l
反查文件属主pacman -Qo /pathdpkg -S /pathyum provides /pathdnf provides /pathzypper search -f /pathapk info -W /pathqfile /pathxbps-query -o /path
列出包文件pacman -Ql pkgdpkg -L pkgrepoquery -l pkgdnf repoquery -l pkgrpm -ql pkgapk info -L pkgequery files pkgxbps-query -f pkg
移除包pacman -R pkg / -Rnsapt remove / apt purgeyum remove pkgdnf remove pkgzypper remove pkgapk del pkgemerge -C pkgxbps-remove pkg / -R
清理孤儿依赖pacman -Rns $(pacman -Qdtq)apt autoremoveyum autoremovednf autoremovezypper packages --unneeded—emerge -acxbps-remove -O
清理包缓存pacman -Sc / -Sccapt cleanyum clean alldnf clean allzypper cleanapk cache cleaneclean-distxbps-remove -O(孤儿)/ 手工清缓存目录

解读与选型:pacman 的独特之处是「一个二进制 + 大写操作字母」贯穿全部生命周期(apt/yum/dnf 是多个子命令工具的组合、dpkg/rpm 只管本地包),-Qo/-F 的文件属主双查询(已装/未装)与 vercmp 版本约束也是同类工具里辨识度最高的设计。跨发行版运维时按表逐列替换即可,语义差异最大的是 Gentoo(源码编译)与 Void(xbps 语法最接近 pacman)。

四、实战示例

4.1 场景一:新装 Arch 服务器初始化(同步 → 修 keyring → 全量升级)

全新系统标准三板斧:强制刷新软件源(换过源的用 -Syy)→ 确保 keyring 最新(避免签名错误)→ 全量升级。以下为本文实测环境的真实执行链(keyring 为最新版时重装无害):

pacman -Syy
pacman -Sy archlinux-keyring --noconfirm
pacman -Syu --noconfirm
pacman -Qu
pacman -Q | wc -l

实测回显(-Syy/keyring/-Syu 完整回显见 3.4/3.27/3.5 节):

$ pacman -Qu
qu_exit=1

$ pacman -Q | wc -l
140

验证闭环:-Qu 退出码 1 = 无可升级包(升级已到位);包总数 140 = 初始 137 + tree(保留的演示包)+ pacman-contrib + fakeroot(实测工具包),-Syu 本身只升级不增包。

4.2 场景二:孤儿包体检与清理(-Qdt + -Rns 闭环)

以 figlet 的完整生命周期演示"装 → 标记为依赖 → 识别孤儿 → 清理":

pacman -S --noconfirm --asdeps figlet
pacman -Qdt
pacman -Rns --noconfirm figlet
pacman -Qdt
echo "exit=$?"

实测回显:

$ pacman -S --noconfirm --asdeps figlet
resolving dependencies...
looking for conflicting packages...

Package (1)   New Version  Net Change  Download Size

extra/figlet  2.2.5-6        0.63 MiB       0.10 MiB

Total Download Size:  0.10 MiB
Total Installed Size:  0.63 MiB

:: Proceed with installation? [Y/n]
:: Retrieving packages...
 figlet-2.2.5-6-x86_64 downloading...
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
:: Processing package changes...
installing figlet...
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
exit=0

$ pacman -Qdt
figlet 2.2.5-6

$ pacman -Rns --noconfirm figlet
checking dependencies...

Package (1)  Old Version  Net Change

figlet       2.2.5-6       -0.63 MiB

Total Removed Size:  0.63 MiB

:: Do you want to remove these packages? [Y/n]
:: Processing package changes...
removing figlet...
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
exit=0

$ pacman -Qdt
exit=1

日常巡检一行版:pacman -Rns --noconfirm $(pacman -Qdtq) || true(-Qdtq 为空时括号展开为空参数导致 -Rns 报错,|| true 吞掉该提示;更稳的写法是先 pacman -Qdtq | grep . 判空再删)。

4.3 场景三:脚本化无人值守安装(-T 预检 + --needed 幂等 + 退出码)

自动化脚本里安装软件的稳妥三段式:-T 预检缺什么 → 只装缺的 → 幂等重跑不报错。本环境 git 未安装、curl/tree 已在,-T 如实只报缺失的 git:

missing=$(pacman -T git curl tree)
echo "missing=[$missing]"
if [ -n "$missing" ]; then
  pacman -S --needed --noconfirm $missing
fi
pacman -S --needed --noconfirm git curl tree
echo "rerun_exit=$?"

实测回显(第一次执行,-T 只报 git → 实际安装 git 及其依赖链共 7 个包):

$ missing=$(pacman -T git curl tree)
$ echo "missing=[git]"
missing=[git]

$ if [ -n "$missing" ]; then
>   pacman -S --needed --noconfirm $missing
> fi
resolving dependencies...
looking for conflicting packages...

Package (7)           New Version  Net Change  Download Size

core/db5.3            5.3.28-7       6.48 MiB       1.26 MiB
core/perl             5.42.3-1      70.34 MiB      20.49 MiB
extra/perl-error      0.17030-3      0.04 MiB       0.02 MiB
extra/perl-mailtools  2.22-3         0.10 MiB       0.06 MiB
extra/perl-timedate   2.35-1         0.15 MiB       0.06 MiB
extra/zlib-ng         2.3.3-1        0.28 MiB       0.11 MiB
extra/git             2.56.0-1      33.54 MiB       7.43 MiB

Total Download Size:    29.43 MiB
Total Installed Size:  110.93 MiB

:: Proceed with installation? [Y/n]
:: Retrieving packages...
 perl-5.42.3-1-x86_64 downloading...
 git-2.56.0-1-x86_64 downloading...
 db5.3-5.3.28-7-x86_64 downloading...
 zlib-ng-2.3.3-1-x86_64 downloading...
 perl-timedate-2.35-1-any downloading...
 perl-mailtools-2.22-3-any downloading...
 perl-error-0.17030-3-any downloading...
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
:: Processing package changes...
installing db5.3...
installing perl...
installing perl-error...
installing perl-timedate...
installing perl-mailtools...
installing zlib-ng...
installing git...
Optional dependencies for git
    git-zsh-completion: upstream zsh completion
    tk: gitk and git gui
    openssh: ssh transport and crypto
    man: show help with `git command --help`
    perl-libwww: git svn
    perl-term-readkey: git svn and interactive.singlekey setting
    perl-io-socket-ssl: git send-email TLS support
    perl-authen-sasl: git send-email TLS support
    perl-cgi: gitweb (web interface) support
    python: git svn & git p4
    subversion: git svn
    org.freedesktop.secrets: keyring credential helper
    libsecret: libsecret credential helper [installed]
    less: the default pager for git
:: Running post-transaction hooks...
(1/4) Creating system user accounts...
Creating group 'git' with GID 969.
Creating user 'git' (git daemon user) with UID 969 and GID 969.
(2/4) Reloading system manager configuration...
  Skipped: Current root is not booted.
(3/4) Arming ConditionNeedsUpdate...
(4/4) Checking for old perl modules...
exit=0

第二次执行(依赖已齐全,--needed 全部跳过,幂等):

$ pacman -S --needed --noconfirm git curl tree
warning: git-2.56.0-1 is up to date -- skipping
warning: curl-8.23.0-1 is up to date -- skipping
warning: tree-2.3.2-1 is up to date -- skipping
 there is nothing to do
rerun_exit=0

💡 闭环验证:-T 只打印缺失项(curl/tree 满足、只报 git)→ 脚本只装缺的;重复执行带 --needed 的 -S 全部 skipping、退出码 0——脚本可以放心跑一百遍。注意安装会连带依赖(git 拖入 perl 全家桶),重装/迁移场景用 --needed 能显著缩短幂等重跑时间。

4.4 场景四:离线批量分发(-Sw 集中下载 + -U 本地安装)

在内网服务器集合中,用一台能上网的机器集中下载、其余机器从共享目录 -U 安装。替代缓存目录必须先创建(3.23 节实测过缺失时的报错),完整真实链路:

mkdir -p /var/tmp/pkgcache
pacman -Sw --noconfirm --cachedir /var/tmp/pkgcache sl
ls /var/tmp/pkgcache/ | grep '^sl-'
pacman -U --noconfirm /var/tmp/pkgcache/sl-5.05-6-x86_64.pkg.tar.zst
pacman -Q sl

实测回显:

$ mkdir -p /var/tmp/pkgcache

$ pacman -Sw --noconfirm --cachedir /var/tmp/pkgcache sl
resolving dependencies...

Package (1)  New Version  Net Change  Download Size

extra/sl     5.05-6         0.03 MiB       0.01 MiB

Total Download Size:  0.01 MiB

:: Proceed with download? [Y/n]
:: Retrieving packages...
 sl-5.05-6-x86_64 downloading...
checking keyring...
checking package integrity...
exit=0

$ ls /var/tmp/pkgcache/ | grep '^sl-'
sl-5.05-6-x86_64.pkg.tar.zst
sl-5.05-6-x86_64.pkg.tar.zst.sig

$ pacman -U --noconfirm /var/tmp/pkgcache/sl-5.05-6-x86_64.pkg.tar.zst
loading packages...
resolving dependencies...
looking for conflicting packages...

Package (1)  New Version  Net Change

sl           5.05-6         0.03 MiB

Total Installed Size:  0.03 MiB

:: Proceed with installation? [Y/n]
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
:: Processing package changes...
installing sl...
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
exit=0

$ pacman -Q sl
sl 5.05-6

分发完成后清理演示残留(移除 sl、删除共享缓存目录):

pacman -Rns --noconfirm sl
rm -rf /var/tmp/pkgcache

实测回显:

$ pacman -Rns --noconfirm sl
checking dependencies...

Package (1)  Old Version  Net Change

sl           5.05-6        -0.03 MiB

Total Removed Size:  0.03 MiB

:: Do you want to remove these packages? [Y/n]
:: Processing package changes...
removing sl...
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
exit=0

两个实测排障点:① 目录被删后再执行 -Sw --cachedir 会报 failed to resolve path '/var/tmp/pkgcache' passed to '--cachedir': No such file or directory(3.23 节);② 包文件不在时 -U 报 error: '/var/tmp/pkgcache/sl-5.05-6-x86_64.pkg.tar.zst': could not find or read package——两者都指向"路径/文件不存在",先 ls 确认再操作。注意:离线分发要连同依赖包文件一起带走(-Sw 会把依赖也下载到缓存目录),目标机 -U 时把目录下所有包文件一起传入:pacman -U --noconfirm /var/tmp/pkgcache/*.pkg.tar.zst。

4.5 场景五:演示包状态复核与重复清理报错(-Q 终态 + -Dk 体检)

本文演示包(sl/cowsay/figlet/htop)已在前文各节逐步清理,这里做终态复核:重复执行批量清理会得到 pacman 的真实报错,再核对保留包与数据库健康度:

pacman -Rns --noconfirm sl cowsay
pacman -Q sl cowsay figlet htop perl
pacman -Q tree
pacman -Dk

实测回显:

$ pacman -Rns --noconfirm sl cowsay
error: target not found: sl
error: target not found: cowsay
exit=1

$ pacman -Q sl cowsay figlet htop perl
perl 5.42.3-1
error: package 'sl' was not found
error: package 'cowsay' was not found
error: package 'figlet' was not found
error: package 'htop' was not found
exit=1

$ pacman -Q tree
tree 2.3.2-1

$ pacman -Dk
No database errors have been found!

💡 三个实测结论:① 已卸载的包重复 -R 会报 error: target not found、退出码 1——清理脚本应先 -Q 包名 判存在再删;② pacman -Q 多参数查询会打印存在的、报错不存在的(perl 因 4.3 节 git 的依赖链回归安装,如实列出),混合查询总是非零退出;③ 收尾 pacman -Dk 报 No database errors have been found! 说明装卸闭环后本地数据库一致、无孤儿损坏——这正是 3.11 节破坏/修复闭环后应有的健康态。

五、注意事项与常见问题

Q1:全新系统执行 pacman 一堆 warning: database file for 'core' does not exist (use '-Sy' to download),是坏了吗? 不是。本地还没有软件源数据库,跑一次 pacman -Sy 即可(见 2.2/3.4 节实测)。之后坚持用 pacman -Syu 做"装/升一体",避免 3.4 节说的部分升级风险。

Q2:安装报 signature from "xxx" is unknown trust / invalid or corrupted package (PGP signature),怎么办? 签名信任链问题,不是包坏了。按 3.27 节实测修复:首选 pacman -Sy archlinux-keyring --noconfirm;若 keyring 已损坏(报错依旧),pacman-key --init && pacman-key --populate archlinux 离线重建,再重试安装。老系统久未升级、或长期 IgnorePkg 了 archlinux-keyring 的机器最容易中招。

Q3:error: failed to synchronize all databases (failed to retrieve some files) 怎么排查? 软件源不可达。按 3.26 节实测路径走:报错行里 failed retrieving file 'core.db' from 主机名 给出了元凶(DNS 解析失败/超时)→ 检查 /etc/pacman.d/mirrorlist,换可达源(官方生成页或 reflector 生成)→ pacman -Syy 强制全量刷新(换源后必须双 y)。

Q4:pacman -Scc --noconfirm 执行完缓存怎么还在? 实测确认的行为:--noconfirm 按方括号默认值应答,"remove ALL files"问句是 [y/N](默认 N),所以被跳过(3.24 节留档)。无人值守清空用 yes | pacman -Scc。另外 pacman 7.x 会留下 download-* 临时目录,-Scc 报 Is a directory 清不掉,手工 rm -rf /var/cache/pacman/pkg/download-*。

Q5:脚本里 pacman 停在 [Y/n] 不动,或者没等确认就退出码 1? pacman 从 stdin 读确认。非交互环境 stdin 为 EOF 时事务直接中止(本文实测 pacman -Sy archlinux-keyring 即触发,exit=1)。脚本一律加 --noconfirm;需要"明确拒绝某些问句"时用 printf 'n\n' | pacman -S ...(3.2 节)或对 [y/N] 类问句用 yes n |。

Q6:为什么大家都说 Arch 上不要 pacman -Sy 后直接 -S 包? -Sy 只刷新数据库、不升级系统。此后安装的包按新依赖版本解析,而系统里其他包还是旧的——这正是"部分升级"(partial upgrade),Arch 滚动模型不支持,轻则依赖报错,重则动态库不匹配导致命令起不来。正确姿势:装包用 pacman -Syu 包名(把 -u 带上),日常更新一律 pacman -Syu。个别包必须暂缓时写进 IgnorePkg(3.25 节实测)。

Q7:pacman -Qo /etc/os-release 报 No package owns,系统被谁改过? 未必。-Qo 只认包文件清单里登记的路径:手工创建的文件、安装脚本运行时生成的文件(如本环境的 /etc/os-release,包里登记的是 /usr/lib/os-release)都不在册(3.16 节实测)。先 pacman -F 文件名 查文件库确认"应属哪个包",再比对实际路径是不是包登记的规范路径。

Q8:pacman -T 'bash>100' 居然不满足,bash 明明是 5.3? 版本比较走 vercmp 语义:按 . 分段逐段数值比较,100 与 5 比较是 100 大,所以 5.3 > 100 不成立(3.22 节实测)。写版本约束时想清楚段位(bash>1 才是"大于 1.x"),拿不准就用 pacman -T 先试。

Q9:pacman -R glibc 想删又删不掉,提示一堆 breaks dependency? 两层保护都在起作用:依赖检查拒绝(glibc 被 100+ 个包依赖,3.25 节实测完整列表)+ HoldPkg 默认名单(HoldPkg = pacman glibc,触发 HoldPkg was found in target list 二次确认)。这两层就是 Arch 不让手滑删库的护栏,不要用 -Rdd 绕过;glibc 出问题的正解是重装系统或 chroot 救援。

Q10:日常巡检与固化建议? ① 更新统一 pacman -Syu,装包统一 pacman -S --needed;② 巡检三件套:pacman -Qdt(孤儿)、pacman -Dk(库完整性)、pacman -Qu | wc -l(落后包数,需先 -Sy);③ 查更新不动库用 pacman-contrib 的 checkupdates(需 fakeroot,缺失时报 Cannot find the fakeroot binary,装 fakeroot 即可——本文实测);④ 缓存治理 paccache -rk1(保留最近一版)优于 -Scc 一刀切;⑤ IgnorePkg 用完记得摘;⑥ 任何 -Rdd/-dd 操作后立刻 pacman -Dk 体检并补齐缺失依赖。

六、参考链接