xbps 命令详解与参数实测(Void Linux)

在 Void Linux(XBPS 0.60.7)实测逐参数讲解 xbps 三件套:xbps-install 的 -S/-u/-y/-c/-f/-R/--repository/-n/-A,xbps-query 的 -l/-R/-Rs/-S/-f/-o/-x/-X/-p/--property/--cat/-H/-m/-O/--regex/-L,xbps-remove 的 -n/-y/-o 孤儿/-R 递归/-O/-OO 缓存清理,以及 xbps-reconfigure 与 /etc/xbps.d/ 换源、ignorepkg、virtualpkg 配置实战,覆盖老镜像默认源迁移、xbps 自升级门禁、依赖版本门槛等真实排障全程。

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

xbps 命令详解与参数实测(Void Linux)

目标:全面掌握 Void Linux 官方包管理器 XBPS 三件套的每一个常用操作——xbps-install 的 -S 同步索引、-u 全量升级、-y 非确认、-c 缓存目录、-f 强制、-R/--repository 指定源、-n 干跑、-A 自动安装;xbps-query 的 -l 已装列表、-R 远程模式、-Rs/-s 搜索、-S 单包详情、-f 文件清单、-o 反查归属、-x/-X 依赖、-p/--property 属性、--cat、-H 持锁、-m/-O 手动与孤儿、--regex、-L 源列表;xbps-remove 的 -n/-y、-o 孤儿清理、-R 连依赖移除、-O/-OO 缓存清理;以及 xbps-reconfigure 重新配置与 /etc/xbps.d/ 换源、ignorepkg、virtualpkg 配置实战,全部命令与回显已在 Void Linux(XBPS 0.60.7)实测通过。

一、环境信息

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

  • 操作系统:Void Linux(cat /etc/os-release 实测 PRETTY_NAME="void")
  • 内核架构:x86_64(uname -m 实测)
  • 包管理器:XBPS。实测起点为镜像内置的 0.59.1(xbps-query --version 回显 XBPS: 0.59.1 API: 20200221 GIT: UNSET),完成全量升级后为 0.60.7(xbps-0.60.7_1),全文参数验证以 0.60.7 为准,两版本行为差异处单独标注
  • 初始状态:最小系统已安装 56 个包,/var/db/xbps/ 中只有本地 pkgdb(pkgdb-0.38.plist 与各包 *-files.plist),没有任何 repodata——即从未同步过远程仓库索引
  • 软件源:/usr/share/xbps.d/00-repository-main.conf 内置 repository=https://alpha.de.repo.voidlinux.org/current,/etc/xbps.d/ 目录为空
  • 相关工具:runit-2.3.1_2、runit-void-20250212_4(服务管理见本专栏 sv 一文)
  • 执行身份:root
  • 演示包(体积小、便于反复装卸):tree 2.2.1、sl 5.05、cowsay 3.8.4(连带 perl/gdbm/less/libxcrypt-devel)、figlet 2.2.5

💡 说明:这是一个"老镜像 + 新仓库"的真实组合——镜像自带的默认源域名 alpha.de.repo.voidlinux.org 已经不是当前推荐域名,直接同步会失败(第二节完整复现并修复),这正是多数老 Void 服务器换源的标准场景。

二、命令概览

2.1 工具分工与 --help 全量回显

XBPS 把功能拆在一组独立可执行文件里,本文聚焦最常用的四个:

工具职责典型命令
xbps-install同步索引、安装、升级xbps-install -S、xbps-install -u、xbps-install <pkg>
xbps-query查询本地库与远程仓库xbps-query -l、xbps-query -Rs、xbps-query -S <pkg>
xbps-remove移除包、清孤儿、清缓存xbps-remove -R <pkg>、xbps-remove -o、xbps-remove -OO
xbps-reconfigure重新执行包的 configure 脚本xbps-reconfigure -f <pkg>

四个工具 --help 的完整实测输出(XBPS 0.60.7)如下。

$ xbps-install --help
Usage: xbps-install [OPTIONS] [PKGNAME...]

OPTIONS
 -A, --automatic             Set automatic installation mode
 -C, --config <dir>          Path to confdir (xbps.d)
 -c, --cachedir <dir>        Path to cachedir
 -d, --debug                 Debug mode shown to stderr
 -D, --download-only         Download packages and check integrity, nothing else
 -f, --force                 Force package re-installation
                             If specified twice, all files will be overwritten.
 -h, --help                  Show usage
 -i, --ignore-conf-repos     Ignore repositories defined in xbps.d
 -I, --ignore-file-conflicts Ignore detected file conflicts
 -U, --unpack-only           Unpack packages in transaction, do not configure them
 -M, --memory-sync           Remote repository data is fetched and stored
                             in memory, ignoring on-disk repodata archives
 -n, --dry-run               Dry-run mode
 -R, --repository <url>      Add repository to the top of the list
                             This option can be specified multiple times
 -r, --rootdir <dir>         Full path to rootdir
     --reproducible          Enable reproducible mode in pkgdb
     --staging               Enable use of staged packages
 -S, --sync                  Sync remote repository index
 -u, --update                Update target package(s)
 -v, --verbose               Verbose messages
 -y, --yes                   Assume yes to all questions
 -V, --version               Show XBPS version
$ xbps-query --help
Usage: xbps-query [OPTIONS] MODE [ARGUMENTS]

OPTIONS
 -C, --config <dir>        Path to confdir (xbps.d)
 -c, --cachedir <dir>      Path to cachedir
 -d, --debug               Debug mode shown to stderr
 -h, --help                Show usage
 -i, --ignore-conf-repos   Ignore repositories defined in xbps.d
 -M, --memory-sync         Remote repository data is fetched and stored
                           in memory, ignoring on-disk repodata archives
 -p, --property PROP[,...] Show properties for PKGNAME
 -R                        Enable repository mode. This mode explicitly
                           looks for packages in repositories
     --repository <url>    Enable repository mode and add repository
                           to the top of the list. This option can be
                           specified multiple times
     --staging             Enable use of staged packages
     --regex               Use Extended Regular Expressions to match
     --fulldeptree         Full dependency tree for -x/--deps
 -r, --rootdir <dir>       Full path to rootdir
 -V, --version             Show XBPS version
 -v, --verbose             Verbose messages

MODE
 -l, --list-pkgs           List installed packages
 -L, --list-repos          List registered repositories
 -H, --list-hold-pkgs      List packages on hold state
     --list-repolock-pkgs  List repolocked packages
 -m, --list-manual-pkgs    List packages installed explicitly
 -O, --list-orphans        List package orphans
 -o, --ownedby FILE        Search for package files by matching STRING or REGEX
 -S, --show PKG            Show information for PKG [default mode]
 -s, --search PKG          Search for packages by matching PKG, STRING or REGEX
     --cat=FILE PKG        Print FILE from PKG binpkg to stdout
 -f, --files PKG           Show package files for PKG
 -x, --deps PKG            Show dependencies for PKG
 -X, --revdeps PKG         Show reverse dependencies for PKG
$ xbps-remove --help
Usage: xbps-remove [OPTIONS] [PKGNAME...]

OPTIONS
 -C, --config <dir>        Path to confdir (xbps.d)
 -c, --cachedir <dir>      Path to cachedir
 -d, --debug               Debug mode shown to stderr
 -F, --force-revdeps       Force package removal even with revdeps or
                           unresolved shared libraries
 -f, --force               Force package files removal
 -h, --help                Show usage
 -n, --dry-run             Dry-run mode
 -O, --clean-cache         Remove outdated packages from the cache
                           If specified twice, also remove uninstalled packages
 -o, --remove-orphans      Remove package orphans
 -R, --recursive           Recursively remove dependencies
 -r, --rootdir <dir>       Full path to rootdir
 -v, --verbose             Verbose messages
 -y, --yes                 Assume yes to all questions
 -V, --version             Show XBPS version
$ xbps-reconfigure --help
Usage: xbps-reconfigure [OPTIONS] [PKGNAME...]

OPTIONS
 -a, --all            Process all packages
 -C, --config <dir>   Path to confdir (xbps.d)
 -d, --debug          Debug mode shown to stderr
 -f, --force          Force reconfiguration
     --fulldeptree    Full dependency tree for -x/--deps
 -h, --help           Show usage
 -i, --ignore PKG     Ignore PKG with -a/--all
 -r, --rootdir <dir>  Full path to rootdir
 -x, --deps           Also process dependencies for each package
 -v, --verbose        Verbose messages
 -V, --version        Show XBPS version

💡 注意 -R 在三个工具里语义完全不同:xbps-install -R 是追加一个仓库到列表顶部(需带 URL),xbps-query -R 是启用远程仓库模式(不带 URL),xbps-remove -R 是递归移除依赖。这是 XBPS 新手最常踩的坑。

2.2 测试数据准备:同步索引与换源(真实故障排障全程)

2.2.1 全新态不同步索引,直接安装必失败

拿到一台从未同步过索引的 Void 机器,直接安装是什么下场?实测:

$ xbps-install -y tree
Package 'tree' not found in repository pool.

$ xbps-query -R -S tree

$ xbps-query -Rs web

$ xbps-install -un

xbps-install 给出一句 Package 'tree' not found in repository pool. 并以退出码 2 结束;而所有带 -R 的远程查询是静默失败(无任何输出,退出码 95)。原因很简单:本地没有任何 repodata,XBPS 对"远程有什么包"一无所知。

💡 结论:全新系统第一件事永远是 xbps-install -S。这条报错是 Void 新手最常见的第一个坑,见 2.2.3 修复后即恢复正常。

2.2.2 老镜像默认源 alpha.de 已失效

直接执行 xbps-install -S 同步内置默认源:

$ xbps-install -S
SSL certificate subject doesn't match host alpha.de.repo.voidlinux.org
ERROR: [reposync] failed to fetch file `https://alpha.de.repo.voidlinux.org/current/x86_64-repodata': Operation not permitted
[*] Updating repository `https://alpha.de.repo.voidlinux.org/current/x86_64-repodata' ...

退出码 95,两个错误叠加:alpha.de.repo.voidlinux.org 的证书 subject 与主机名不匹配,索引文件也拉不下来。这是老镜像的历史遗留——Void 官方早已把主源迁到 repo-default.voidlinux.org。

先用命令行参数临时指定新源,验证可达性(--repository 用法详见 3.1.6):

$ xbps-install --repository=https://repo-default.voidlinux.org/current -S
[*] Updating repository `https://repo-default.voidlinux.org/current/x86_64-repodata' ...
x86_64-repodata: [2166KB 0%] 244MB/s ETA: 00m00s
x86_64-repodata: [2166KB 4%] 186KB/s ETA: 00m21s
x86_64-repodata: [2166KB 71%] 1004KB/s ETA: 00m00s
x86_64-repodata: 2166KB [avg rate: 1401KB/s]
ERROR: [reposync] failed to fetch file `https://alpha.de.repo.voidlinux.org/current/x86_64-repodata': Bad Request
[*] Updating repository `https://alpha.de.repo.voidlinux.org/current/x86_64-repodata' ...

新源 2166KB 索引下载成功;但整条命令仍以默认源里那条坏源的报错收尾(整体退出码为 0)。此时远程查询已经可用:

$ xbps-query --repository=https://repo-default.voidlinux.org/current -S tree
architecture: x86_64
changelog: https://oldmanprogrammer.net/source.php?dir=projects/tree/CHANGES
filename-sha256: 7b0755384ad83eb29b07614a36e44516f530671d47ed7466566107322beda6b4
filename-size: 45KB
homepage: https://oldmanprogrammer.net/source.php?dir=projects/tree
installed_size: 104KB
license: GPL-2.0-or-later
maintainer: icp <pangolin@vivaldi.net>
pkgname: tree
pkgver: tree-2.2.1_1
repository: https://repo-default.voidlinux.org/current
run_depends:
	glibc>=2.39_1
shlib-requires:
	libc.so.6
short_desc: Recursive directory listing program
source-revisions: tree:5c746e06418

💡 注意 run_depends: glibc>=2.39_1:当前源上最新的 tree 2.2.1 依赖 glibc 2.39,而这台老镜像只有 glibc 2.32——直接装会因依赖门槛失败,必须先做全量升级(2.2.4),这是老系统与新仓库配合的第二道坎。

2.2.3 永久换源:/etc/xbps.d/ 覆盖默认配置

XBPS 的配置优先级是 /etc/xbps.d/*.conf 覆盖 /usr/share/xbps.d/*.conf 中同名文件。内置有 4 个文件:

$ ls /usr/share/xbps.d/
00-repository-main.conf
void-virtualpkgs.conf
xbps-arch.conf
xbps.conf

在 /etc/xbps.d/ 写一个同名文件,把源指向 repo-default:

$ printf "repository=https://repo-default.voidlinux.org/current\n" > /etc/xbps.d/00-repository-main.conf
$ cat /etc/xbps.d/00-repository-main.conf
repository=https://repo-default.voidlinux.org/current

再次同步,这次干净利落:

$ xbps-install -S
[*] Updating repository `https://repo-default.voidlinux.org/current/x86_64-repodata' ...

退出码 0,alpha.de 的报错彻底消失。确认源已注册:

$ xbps-query -L
14823 https://repo-default.voidlinux.org/current (RSA signed)

-L 列出 1 个源、14823 个包、RSA 签名可信。repodata 落盘位置在 /var/db/xbps/ 下按"源 URL 转义后"命名的子目录里(如 /var/db/xbps/https___repo-default.voidlinux.org_current/x86_64-repodata),不在顶层目录直接能 grep 到。

💡 换源要点:写同名文件 00-repository-main.conf 是替换默认源;如果写成别的文件名(如 10-myrepo.conf),repository= 行是追加新源,旧的 alpha.de 依旧会被尝试同步而继续报错。老系统换源务必用同名覆盖。

2.2.4 xbps 自升级门禁与全量升级

在 glibc 2.32 的老基线上直接全量升级,XBPS 会先拒绝:

$ xbps-install -uy
The 'xbps' package must be updated, please run `xbps-install -u xbps`

退出码 16。这是 XBPS 的自我保护:库与工具自身有大版本跨越时,必须先把 xbps 包升上去再谈其他。先看自升级这一步要动哪些东西(非交互环境忘记加 -y 会怎样也一并实录):

$ xbps-install -u xbps
Do you want to continue? [Y/n] 8 packages will be downloaded:

4 packages will be installed:

  libxcrypt-compat-4.4.38_1
  libcrypto3-3.6.5_1
  libssl3-3.6.5_1
  base-container-0.3_3
4 packages will be updated:

  glibc (2.32_2 -> 2.41_1)
  libxbps (0.59.1_5 -> 0.60.7_1)
  xbps (0.59.1_5 -> 0.60.7_1)
  base-minimal (0.3_1 -> 0.3_3)

Size to download:               12MB
Size required on disk:          40MB
Space available on disk:       187GB

Aborting!

标准输入是空的非交互环境里,读不到确认输入,XBPS 打印 Aborting! 退出——自动化脚本必须带 -y。补上 -y 执行自升级:

$ xbps-install -uy xbps
8 packages will be downloaded:

4 packages will be installed:

  libxcrypt-compat-4.4.38_1
  libcrypto3-3.6.5_1
  libssl3-3.6.5_1
  base-container-0.3_3
4 packages will be updated:

  glibc (2.32_2 -> 2.41_1)
  libxbps (0.59.1_5 -> 0.60.7_1)
  xbps (0.59.1_5 -> 0.60.7_1)
  base-minimal (0.3_1 -> 0.3_3)

Size to download:               12MB
Size required on disk:          40MB
Space available on disk:       187GB


[*] Downloading packages
libxcrypt-compat-4.4.38_1.x86_64.xbps.sig: [512B 100%] 27MB/s ETA: 00m00s
libxcrypt-compat-4.4.38_1.x86_64.xbps.sig: 512B [avg rate: 27MB/s]
...
glibc-2.41_1: verifying RSA signature...

完成后 xbps 升到 0.60.7,glibc 升到 2.41。此时全量升级畅通:

$ xbps-install -uy
...
59 downloaded, 8 installed, 51 updated, 59 configured, 0 removed, 0 on hold.

$ xbps-install -un

$ xbps-query -l | wc -l
68

$ xbps-query -l | tail -5
ii util-linux-common-2.41.4_1       Miscellaneous linux utilities - common files
ii which-2.23_1                     Displays where a particular program in your path is located
ii xbps-0.60.7_1                    XBPS package system utilities
ii xbps-triggers-0.131_1           XBPS triggers for Void Linux
ii zlib-1.3.2_1                     Compression/decompression Library

一轮升级合计 59 个包下载、8 个新装、51 个更新;-un 干跑确认再无待升级项;包数从 56 变为 68。此后全文所有参数实测都在这套 0.60.7 + glibc 2.41 的新基线上进行。

三、参数逐项实测

3.1 xbps-install:安装与升级

3.1.1 <pkg>:安装一个包

装演示包 tree,看一遍完整的安装流水线:

$ xbps-install -y tree
1 package will be downloaded:

  tree-2.2.1_1
1 package will be installed:

  tree-2.2.1_1

Size to download:               46KB
Size required on disk:         104KB
Space available on disk:       184GB


[*] Downloading packages
tree-2.2.1_1.x86_64.xbps.sig2: [512B 100%] 54MB/s ETA: 00m00s
tree-2.2.1_1.x86_64.xbps.sig2: 512B [avg rate: 54MB/s]
tree-2.2.1_1.x86_64.xbps: [45KB 8%] 279MB/s ETA: 00m00s
tree-2.2.1_1.x86_64.xbps: 45KB [avg rate: 3151MB/s]
tree-2.2.1_1: verifying RSA signature...

[*] Collecting package files
tree-2.2.1_1: collecting files...

[*] Unpacking packages
tree-2.2.1_1: unpacking ...

[*] Configuring unpacked packages
tree-2.2.1_1: configuring ...
tree-2.2.1_1: installed successfully.

1 downloaded, 1 installed, 0 updated, 1 configured, 0 removed, 0 on hold.

流水线五阶段:Downloading → Verifying integrity(RSA 签名校验)→ Collecting files → Unpacking → Configuring,末行是事务汇总。装完验证:

$ tree --version
tree v2.2.1 (c) 1996 - 2024 by Steve Baker, Thomas Moore, Francesc Rocher, Florian Sesser, Kyosuke Tokoro

$ xbps-query tree | grep -E "pkgver|install-date|repository|automatic-install"
install-date: 2026-10-17 00:22 UTC
pkgver: tree-2.2.1_1
repository: https://repo-default.voidlinux.org/current

💡 手动安装的包没有 automatic-install 字段(默认 no);.sig2 后缀是新一代双签名文件,老包缓存里也会见到 .sig。

3.1.2 -y --yes:免确认(自动化必备)

上面的示例已带 -y。如果不带,XBPS 在事务前会打印同样的清单并等待 Do you want to continue? [Y/n]——人工交互按回车默认 Y;在 cron、脚本等无标准输入的场景则会直接 Aborting!(见 2.2.4 实录)。所有自动化场景一律 -y。

3.1.3 重复安装:already installed,但退出码为 0

$ xbps-install -y tree
ERROR: Package `tree' already installed.

报 ERROR 但退出码是 0,幂等安全。批量脚本里"确保已安装"直接 xbps-install -y <pkg> 即可,无需先查询。

3.1.4 -f --force:强制重装

$ xbps-install -fy tree
1 package will be installed:

  tree-2.2.1_1

Size required on disk:         104KB
Space available on disk:       184GB


[*] Verifying package integrity
tree-2.2.1_1: verifying RSA signature...

[*] Collecting package files
tree-2.2.1_1: collecting files...
tree-2.2.1_1: collecting files...

[*] Unpacking packages
tree-2.2.1_1: unpacking ...

[*] Configuring unpacked packages
tree-2.2.1_1: configuring ...
tree-2.2.1_1: installed successfully.

0 downloaded, 1 installed, 0 updated, 1 configured, 0 removed, 0 on hold.

0 downloaded:文件还在缓存目录里,直接解包覆盖。help 原文注明 -f 写两次(-ff)会覆盖所有文件(包括标记为 preserve 的配置),慎用。

3.1.5 -c --cachedir:自定义缓存目录

$ xbps-install -yc /var/cache/xbps-alt sl
1 package will be downloaded:

  sl-5.05_1
1 package will be installed:

  sl-5.05_1

Size to download:              9981B
Size required on disk:          36KB
Space available on disk:       184GB

...
1 downloaded, 1 installed, 0 updated, 1 configured, 0 removed, 0 on hold.

$ ls -la /var/cache/xbps-alt/
total 24
drwxr-xr-x 2 root root 4096 Oct 17 00:22 .
drwxr-xr-x 1 root root 4096 Oct 17 00:22 ..
-rw-r--r-- 1 root root 9469 Sep  9  2023 sl-5.05_1.x86_64.xbps
-rw-r--r-- 1 root root  512 Sep  9  2023 sl-5.05_1.x86_64.xbps.sig2

目录不存在会自动创建,.xbps 二进制包与 .sig2 签名一起落盘。对照组:默认缓存目录 /var/cache/xbps/ 存放其他包的缓存。多装几个包后自定义目录内容:

$ ls /var/cache/xbps-alt/
cowsay-3.8.4_1.x86_64.xbps
cowsay-3.8.4_1.x86_64.xbps.sig2
gdbm-1.26_1.x86_64.xbps
gdbm-1.26_1.x86_64.xbps.sig2
less-692_1.x86_64.xbps
less-692_1.x86_64.xbps.sig2
libxcrypt-devel-4.4.38_1.x86_64.xbps
libxcrypt-devel-4.4.38_1.x86_64.xbps.sig2
perl-5.42.3_1.x86_64.xbps
perl-5.42.3_1.x86_64.xbps.sig2
sl-5.05_1.x86_64.xbps
sl-5.05_1.x86_64.xbps.sig2

3.1.6 -R/--repository:临时指定仓库

-R <url> 把指定仓库加到源列表顶部,仅本次命令生效。短参与长参等价:

$ xbps-install -R https://mirror.sjtu.edu.cn/voidlinux/current -ny figlet
figlet-2.2.5_6 install x86_64 https://repo-default.voidlinux.org/current 672593 94372

$ xbps-install --repository=https://mirror.sjtu.edu.cn/voidlinux/current -yn figlet
figlet-2.2.5_6 install x86_64 https://repo-default.voidlinux.org/current 672593 94372

💡 两个值得注意的实测细节:① 干跑输出显示 figlet 实际解析自 repo-default 而非 SJTU 镜像——两个源里都有同版本包时,仍按解析优先级落在主源,-R 只是把候选源排到最前;② -n 干跑一行格式为 pkgver 动作 架构 源 已装大小 包文件大小,是把安装计划接入自动化脚本的标准出口。

3.1.7 -n --dry-run:事务干跑

$ xbps-install -n figlet
figlet-2.2.5_6 install x86_64 https://repo-default.voidlinux.org/current 672593 94372

不落盘、不下载,只输出将要发生的事。升级前用 -un 看待升级清单(格式同上,动作字段为 update):

$ xbps-install -un
libxcrypt-compat-4.4.38_1 install x86_64 https://repo-default.voidlinux.org/current 206920 89590
glibc-2.41_1 update x86_64 https://repo-default.voidlinux.org/current 33363382 9170635
...
xbps-0.60.7_1 update x86_64 https://repo-default.voidlinux.org/current 533481 121137

3.1.8 -u --update:全量/指定升级

-u 不带包名即全量升级(配合 -y 免确认),带包名即升级指定包(xbps-install -u xbps 即自升级门禁的标准解法,见 2.2.4)。升级完成的汇总行含义一目了然:

59 downloaded, 8 installed, 51 updated, 59 configured, 0 removed, 0 on hold.

💡 -D --download-only 只下载校验不安装,适合先热缓存再择机安装;-U --unpack-only 解包不执行 configure。这两个参数本文未单独展开,行为以 help 原文为准。

3.1.9 -A --automatic:依赖式安装(配合孤儿管理)

$ xbps-install -Ay figlet
1 package will be downloaded:

  figlet-2.2.5_6
1 package will be installed:

  figlet-2.2.5_6

Size to download:               93KB
Size required on disk:         657KB
Space available on disk:       180GB

...
1 downloaded, 1 installed, 0 updated, 1 configured, 0 removed, 0 on hold.

$ xbps-query -O
figlet-2.2.5_6

-A 把包标记为 automatic-install=yes(模拟"作为依赖装进来"的状态)——没有任何被依赖者的它立刻被 -O 判定为孤儿。这个特性正是 3.3.2 孤儿管理机制的判定基础:孤儿 = 已安装 && automatic-install=yes && 没有任何包依赖它。手动安装(无 -A)的包永远不会成为孤儿。

3.2 xbps-query:查询

3.2.1 -l --list-pkgs:已安装列表

$ xbps-query -l | head -6
ii acl-2.4.0_1                      Access Control List filesystem support
ii attr-2.6.0_1                     Extended attribute support library for ACL support
ii base-container-0.3_3             Void Linux base system meta for minimal containers/chroots
ii base-files-0.146_1               Void Linux base system files
ii base-minimal-0.3_3               Void Linux base system meta for minimal containers/chroots (transitional dummy package)
ii bzip2-1.0.8_2                    Freely available, patent free, high-quality data compressor

ii 前缀沿用 dpkg 风格(installed + installed-config),行数即包数:

$ xbps-query -l | wc -l
68

3.2.2 -s --search:本地搜索

$ xbps-query -s tree
[*] libsmartcols-2.41.4_1 Table or Tree library from util-linux
[*] tree-2.2.1_1          Recursive directory listing program

[*] 表示已安装(未安装的本地搜索不出现);匹配域包括包名与描述,所以 libsmartcols 因描述里有 "Tree library" 被带了出来。

3.2.3 -Rs:远程仓库搜索

$ xbps-query -Rs figlet | head -8
[-] figlet-2.2.5_6           Program for making large letters out of ordinary text
[-] figlet-fonts-20150508_4  Additional fonts for figlet
[-] python3-pyfiglet-0.8.0_8 Implementation of figlet written in Python

[-] 表示未安装。-Rs 等价于 -R + -s:启用远程模式后搜索整个仓库池。

3.2.4 -S --show:单包详情

对已安装包查详情(-S 是 xbps-query 的默认模式,xbps-query tree 与 xbps-query -S tree 等价):

$ xbps-query -S tree
architecture: x86_64
changelog: https://oldmanprogrammer.net/source.php?dir=projects/tree/CHANGES
filename-sha256: 7b0755384ad83eb29b07614a36e44516f530671d47ed7466566107322beda6b4
filename-size: 45KB
homepage: https://oldmanprogrammer.net/source.php?dir=projects/tree
install-date: 2026-10-17 00:24 UTC
installed_size: 104KB
license: GPL-2.0-or-later
maintainer: icp <pangolin@vivaldi.net>
metafile-sha256: cd2c527d2fcfd14187266636a42ba703fc6b4d1655920c8d588f2ad4fd165f62
pkgname: tree
pkgver: tree-2.2.1_1
repository: https://repo-default.voidlinux.org/current
run_depends:
	glibc>=2.39_1
shlib-requires:
	libc.so.6
short_desc: Recursive directory listing program
source-revisions: tree:5c746e06418
state: installed

对照 -R -S(强制查远程仓库模式):

$ xbps-query -R -S tree
architecture: x86_64
changelog: https://oldmanprogrammer.net/source.php?dir=projects/tree/CHANGES
filename-sha256: 7b0755384ad83eb29b07614a36e44516f530671d47ed7466566107322beda6b4
filename-size: 45KB
homepage: https://oldmanprogrammer.net/source.php?dir=projects/tree
installed_size: 104KB
license: GPL-2.0-or-later
maintainer: icp <pangolin@vivaldi.net>
pkgname: tree
pkgver: tree-2.2.1_1
repository: https://repo-default.voidlinux.org/current
run_depends:
	glibc>=2.39_1
shlib-requires:
	libc.so.6
short_desc: Recursive directory listing program
source-revisions: tree:5c746e06418

💡 字段差异:本地详情多出 install-date 与 state 两个运行时字段;远程模式纯静态元数据。排障时 install-date 是判断"这台机器什么时候被动过"的利器。

3.2.5 -f --files:包文件清单

$ xbps-query -f tree
/usr/bin/tree
/usr/share/man/man1/tree.1

含符号链接的包(cowsay 的 cowthink 是指向 cowsay 的链接):

$ xbps-query -f cowsay
/usr/bin/cowsay
/usr/share/cowsay/cows/actually.cow
/usr/share/cowsay/cows/alpaca.cow
...
/usr/share/man/man1/cowsay.1
/usr/bin/cowthink -> /usr/bin/cowsay
/usr/share/man/man1/cowthink.1 -> /usr/share/man/man1/cowsay.1

普通文件直接列路径,符号链接以 链接名 -> 目标 形式单独列在末尾。

3.2.6 -o --ownedby:反查文件属于哪个包

$ xbps-query -o /usr/bin/tree
tree-2.2.1_1: /usr/bin/tree (regular file)

支持 glob,但必须加引号——不加引号时 shell 先展开通配符,若展开出多个参数 XBPS 直接拒绝:

$ xbps-query -o /usr/bin/cow*
ERROR: xbps-query: too many arguments

(此时 /usr/bin/ 下恰好有 cowsay、cowthink 两个文件,shell 展开成两个参数。)加引号后由 xbps 自己做匹配:

$ xbps-query -o "/usr/bin/cow*"
cowsay-3.8.4_1: /usr/bin/cowsay (regular file)
cowsay-3.8.4_1: /usr/bin/cowthink -> /usr/bin/cowsay (link)

💡 另一个实测细节:-o 匹配的是完整路径模式,纯文件名模式不命中——xbps-query -o "cowthink" 无输出(退出码 0)。不确定路径时用 "/usr/bin/cow*" 这类带目录的形式。

3.2.7 -x --deps 与 -X --revdeps:依赖与反向依赖

$ xbps-query -x cowsay
perl>=0

$ xbps-query -X perl
cowsay-3.8.4_1

$ xbps-query -X less
perl-5.42.3_1

-x 列出"我依赖谁"(cowsay 只依赖 perl>=0);-X 列出"谁依赖我"(perl 被 cowsay 依赖;less 被 perl 依赖)。移除前的依赖影响评估就靠 -X。

3.2.8 -p/--property:只取指定属性

逗号分隔属性清单,适合脚本取值:

$ xbps-query -p version,short_desc,homepage tree
Recursive directory listing program
https://oldmanprogrammer.net/source.php?dir=projects/tree

$ xbps-query --property=short_desc sl
Correct you if you type (sl) by mistake

💡 两个实测行为:① 属性清单里写了 version,但输出只有两行——无效/不存在的属性名被静默跳过,不报错(tree 的版本属性名是 pkgver);② help 里 PROP[,...] 支持从标准输入读属性清单(传 -),实测 printf "version\nshort_desc\n" | xbps-query --property=- tree 在 0.60.7 下无输出,该特性按 help 存在但此场景未生效,用逗号分隔形式最稳妥。

3.2.9 --cat:从包文件中读取文件

$ xbps-query --cat=/usr/share/licenses/tree/LICENSE tree

输出为空、退出码 0。原因:tree 包里并没有这个文件(xbps-query -f tree 只有 /usr/bin/tree 和 man 页)。--cat 对包内不存在的文件不报错,使用前先用 -f 确认路径。

3.2.10 -H --list-hold-pkgs 与 xbps-pkgdb hold/unhold

-H 列出处于 hold(持锁,禁止升级)状态的包。锁操作由配套工具 xbps-pkgdb -m 完成:

$ xbps-query -H

$ xbps-pkgdb -m hold tree

$ xbps-query -H
tree-2.2.1_1

$ xbps-query tree | grep -E "pkgver|state"
pkgver: tree-2.2.1_1
state: installed

$ xbps-pkgdb -m unhold tree

$ xbps-query -H

hold 后 state 仍是 installed,持锁状态体现在 -H 列表与 pkgdb 元数据里;-u 全量升级会跳过持锁包。

3.2.11 -m --list-manual-pkgs 与 -O --list-orphans

$ xbps-query -m
base-minimal-0.3_3
cowsay-3.8.4_1
sl-5.05_1
tree-2.2.1_1

-m 列出手动安装(非 automatic)的包——一台机器"到底装了什么"的最小集。-O 列孤儿:

$ xbps-query -O
libpcre-8.45_3
libssl1.1-1.1.1w_1
libcrypto1.1-1.1.1w_1

这 3 个孤儿正是 2.2.4 那轮大升级留下的:xbps/grep 等切换到 libssl3/pcre2 后,旧运行库 libssl1.1/libcrypto1.1/libpcre 无人依赖又处于 automatic 状态。升级后跑一遍 -O 是 Void 运维的标准收尾动作。

3.2.12 --regex:正则匹配

$ xbps-query --regex -s "^tree"
[*] tree-2.2.1_1 Recursive directory listing program

$ xbps-query --regex -s "^libsmart"
[*] libsmartcols-2.41.4_1 Table or Tree library from util-linux

$ xbps-query --regex -s "^tree$"

💡 实测规律:--regex 启用扩展正则且大小写不敏感(tree 能匹配描述里的 "Tree");匹配串是"包名-版本"整体(如 tree-2.2.1_1),所以 $ 锚点想精确匹配包名时必须带上版本尾巴或用 ^tree-,^tree$ 永远查不到东西。

3.2.13 -L --list-repos:已注册源列表

$ xbps-query -L
14823 https://repo-default.voidlinux.org/current (RSA signed)

格式:包数量 源URL (签名状态)。同步失败的源不会出现在这里(见 2.2.2 的空输出阶段)。

3.3 xbps-remove:移除与清理

3.3.1 <pkg> + -n 干跑 + -y:标准移除

$ xbps-remove -ny sl
sl-5.05_1 remove x86_64 https://repo-default.voidlinux.org/current 36429 9469

干跑一行给出:pkgver、动作、架构、来源源、已装大小、缓存文件大小。执行移除:

$ xbps-remove -y sl
1 package will be removed:

  sl-5.05_1

Size freed on disk:             36KB
Space available on disk:       180GB

Removing `sl-5.05_1' ...
Removed `sl-5.05_1' successfully.

0 downloaded, 0 installed, 0 updated, 0 configured, 1 removed, 0 on hold.

移除后再查这个包,与全新态远程查询一样静默退出(退出码 2):

$ xbps-query sl

💡 xbps-query -S <未安装包名> 无输出、退出码 2,脚本里判断"是否已安装"直接看退出码即可。

3.3.2 -o --remove-orphans:孤儿一键清理

3.2.11 查到的 7 个孤儿(3 个升级残留 + 4 个 cowsay 依赖连带)一次清空:

$ xbps-remove -oy
7 packages will be removed:

  libpcre-8.45_3
  libssl1.1-1.1.1w_1
  perl-5.42.3_1
  gdbm-1.26_1
  less-692_1
  libcrypto1.1-1.1.1w_1
  libxcrypt-devel-4.4.38_1

Size freed on disk:             78MB
Space available on disk:       180GB

Removing `libpcre-8.45_3' ...
Removed `libpcre-8.45_3' successfully.
...
0 downloaded, 0 installed, 0 updated, 0 configured, 7 removed, 0 on hold.

$ xbps-query -O

$ xbps-query -l | wc -l
66

孤儿判定标准回顾(3.1.9):automatic 状态 + 无人依赖。所以手动装的包绝不会被 -o 误删;反过来,用 -A 装的东西立刻是孤儿:

$ xbps-query -O
figlet-2.2.5_6

$ xbps-remove -oy
1 package will be removed:

  figlet-2.2.5_6
...
0 downloaded, 0 installed, 0 updated, 0 configured, 1 removed, 0 on hold.

3.3.3 -R --recursive:连依赖一起移除

cowsay 只依赖 perl,perl 又连带 libxcrypt-devel/less 等。普通移除只删 cowsay 本体(依赖变成孤儿留给 -o),-R 则把这条依赖链在事务里一起移除:

$ xbps-query -x cowsay
perl>=0

$ xbps-remove -nR cowsay
cowsay-3.8.4_1 remove x86_64 https://repo-default.voidlinux.org/current 43323 19174
perl-5.42.3_1 remove x86_64 https://repo-default.voidlinux.org/current 75780310 15795017
libxcrypt-devel-4.4.38_1 remove x86_64 https://repo-default.voidlinux.org/current 326015 112501
less-692_1 remove x86_64 https://repo-default.voidlinux.org/current 432099 163043
$ xbps-remove -yR cowsay
4 packages will be removed:

  cowsay-3.8.4_1
  perl-5.42.3_1
  libxcrypt-devel-4.4.38_1
  less-692_1

Size freed on disk:             73MB
Space available on disk:       173GB

Removing `cowsay-3.8.4_1' ...
Removed `cowsay-3.8.4_1' successfully.
Removing `perl-5.42.3_1' ...
Removed `perl-5.42.3_1' successfully.
Removing `libxcrypt-devel-4.4.38_1' ...
Removed `libxcrypt-devel-4.4.38_1' successfully.
Removing `less-692_1' ...
Removed `less-692_1' successfully.

0 downloaded, 0 installed, 0 updated, 0 configured, 4 removed, 0 on hold.

💡 -R 只递归"移除目标的依赖",不会动别人也依赖的包(如 less 同时被其他包需要时不会被列入事务)。移除前务必先 -nR 看清单——把 perl 这类基础设施包从系统里整个带走的风险要心里有数;真要强行移除还有反向依赖的包得用 -F --force-revdeps(危险,本文未实测)。

3.3.4 -O --clean-cache 与 -OO:缓存清理的两档

help 原文:-O 清"过时"缓存包;-O 写两次连已卸载包的缓存一起清。实测对照——先看当时缓存里有什么(8 个文件属于已卸载或过时域):

$ ls /var/cache/xbps/ | grep -cE "cowsay|perl|less|gdbm"
8

$ xbps-remove -Oy

单次 -Oy 无输出、退出码 0——缓存里没有"同包旧版本"意义上的过时文件,什么都不清。加第二个 -O:

$ xbps-remove -OOy
Removed libssl1.1-1.1.1w_1.x86_64.xbps from cachedir (obsolete)
Removed figlet-2.2.5_6.x86_64.xbps from cachedir (obsolete)
Removed libcrypto1.1-1.1.1w_1.x86_64.xbps from cachedir (obsolete)
Removed libpcre-8.45_3.x86_64.xbps from cachedir (obsolete)
Removed cowsay-3.8.4_1.x86_64.xbps from cachedir (obsolete)

💡 关键对照:此时 perl/gdbm/less 的缓存文件还在——因为这些包当时仍处于已安装状态,不属于 -OO 的清理范围(help 原文 "also remove uninstalled packages");随后 -oy 移除这 4 个孤儿后,它们的缓存会留到下一次 -OO 才被清。要彻底瘦身缓存:先 -oy 清孤儿、再 -OOy 清缓存。tree 的缓存(当前已安装)始终保留:

$ ls /var/cache/xbps/ | grep -c tree
2

3.3.5 移除族参数速查

参数作用实测要点
-n干跑输出单行事务计划
-y免确认自动化必备
-o清孤儿只动 automatic 且无人依赖的包
-R递归移除依赖先 -nR 审清单
-O清过时缓存本例无可清,静默
-OO连已卸载包缓存一起清实测精确按"已卸载"判定
-F无视反向依赖强删危险参数,未实测

3.4 xbps-reconfigure:重新配置

包安装后的"配置阶段"(Configuring unpacked packages)执行包自带的 configure 脚本(建用户、生成符号链接、重建缓存等)。系统迁移、配置变更后可用 xbps-reconfigure -f 手工重跑:

$ xbps-reconfigure -f tree
tree: configuring ...
tree: configured successfully.

$ xbps-reconfigure -f ca-certificates
ca-certificates: configuring ...
ca-certificates: configured successfully.

ca-certificates 的 configure 脚本会重建 /etc/ssl/certs/ 下的证书哈希符号链接,重配置后时间戳全部刷新:

$ ls -la /etc/ssl/certs/ | head -6
total 800
drwxr-xr-x 1 root root  24576 Oct 17 00:24 .
drwxr-xr-x 1 root root   4096 Oct 17 00:19 ..
lrwxrwxrwx 1 root root     23 Oct 17 00:24 002c0b4f.0 -> GlobalSign_Root_R46.pem
lrwxrwxrwx 1 root root     24 Oct 17 00:24 0179095f.0 -> BJCA_Global_Root_CA1.pem
lrwxrwxrwx 1 root root     45 Oct 17 00:24 02265526.0 -> Entrust_Root_Certification_Authority_-_G2.pem

💡 典型场景:改完 /etc/default/libc-locales 后 xbps-reconfigure -f glibc-locales;glibc 大版本升级后对全系统 xbps-reconfigure -a。输出极简,只有两行——没有"成功重建 N 个链接"之类的进度,验证要靠副作用(如上面的哈希链接时间戳)。

3.5 /etc/xbps.d/ 配置实战

3.5.1 换源(00-repository-main.conf)

完整过程见 2.2.3。要点回顾:/etc/xbps.d/ 同名文件覆盖 /usr/share/xbps.d/;repository=<url> 一行一个源,文件内多行按顺序生效。

3.5.2 ignorepkg:忽略包(作用域有限)

$ printf "ignorepkg=tree\n" > /etc/xbps.d/10-ignorepkg.conf

先卸载再显式安装,实测 ignorepkg 不会拦截显式指定的安装目标:

$ xbps-remove -y tree
...
0 downloaded, 0 installed, 0 updated, 0 configured, 1 removed, 0 on hold.

$ xbps-install -y tree
1 package will be installed:

  tree-2.2.1_1
...
tree-2.2.1_1: installed successfully.

0 downloaded, 1 installed, 0 updated, 1 configured, 0 removed, 0 on hold.

$ xbps-query tree | grep -E "pkgver|state"
pkgver: tree-2.2.1_1
state: installed

ignorepkg 的设计意图是让 XBPS 在依赖解析与批量升级中跳过该包(例如禁用某个会被自动拉起的内核变体),不要指望它当"安装黑名单"用。验证完删除:

$ rm /etc/xbps.d/10-ignorepkg.conf

3.5.3 virtualpkg:虚拟包映射

/usr/share/xbps.d/void-virtualpkgs.conf 在当前版本实测为空文件(占位)。自定义一个"editor 指向 nvi"的映射:

$ printf "virtualpkg=editor-1_0:nvi\n" > /etc/xbps.d/20-virtualpkg.conf
$ xbps-query nvi | grep pkgver
pkgver: nvi-1.81.6_19

查询模式不解析虚拟包:

$ xbps-query -S editor | head -8

但事务模式(安装)会解析:

$ xbps-install -n editor
nvi-1.81.6_19 install x86_64 https://repo-default.voidlinux.org/current 594781 253913

真实执行,nvi 被重新落实一遍(包括重建 vi alternatives 组符号链接):

$ xbps-install -y editor
1 package will be installed:

  nvi-1.81.6_19

Size required on disk:         581KB
Space available on disk:       176GB


[*] Verifying package integrity
nvi-1.81.6_19: verifying RSA signature...

[*] Collecting package files
nvi-1.81.6_19: collecting files...
nvi-1.81.6_19: collecting files...

[*] Unpacking packages
nvi-1.81.6_19: unpacking ...
Creating 'vi' alternatives group symlink: ex -> /usr/bin/nex
Creating 'vi' alternatives group symlink: ex.1 -> /usr/share/man/man1/nex.1
Creating 'vi' alternatives group symlink: vi -> /usr/bin/nvi
Creating 'vi' alternatives group symlink: vi.1 -> /usr/share/man/man1/nvi.1
Creating 'vi' alternatives group symlink: view -> /usr/bin/nview
Creating 'vi' alternatives group symlink: view.1 -> /usr/share/man/man1/nvi.1

[*] Configuring unpacked packages
nvi-1.81.6_19: configuring ...
nvi-1.81.6_19: installed successfully.

0 downloaded, 1 installed, 0 updated, 1 configured, 0 removed, 0 on hold.

虚拟包映射格式为 virtualpkg=<虚拟名>-<版本>:<真实包名>,典型用途是 cron-daemon、editor 这类"多选一"角色位。验证完删除:

$ rm /etc/xbps.d/20-virtualpkg.conf
$ xbps-query -L
14823 https://repo-default.voidlinux.org/current (RSA signed)

3.5.4 xbps.conf 主配置关键字

/usr/share/xbps.d/xbps.conf 是带完整注释的样例(上文 2.2 之前的环境探查中已完整采集),常用键:

  • #rootdir=/:目标根目录(跨根/救援场景)
  • #cachedir=var/cache/xbps:缓存目录(相对 rootdir)
  • #syslog=true:是否写 syslog
  • #bestmatching=true:开启后跨源选最高版本,而不是用第一个匹配到的源
  • keepconf / preserve:配置文件保留与文件保全策略

修改系统级默认值时,把对应行写进 /etc/xbps.d/ 下的新文件即可(不必整份覆盖 xbps.conf)。

四、实战示例

4.1 老 Void 服务器的标准初始化

# 1) 换源(老镜像默认源已失效)
printf "repository=https://repo-default.voidlinux.org/current\n" > /etc/xbps.d/00-repository-main.conf
# 2) 同步索引
xbps-install -S
# 3) 先自升级 xbps(门禁要求),再全量升级
xbps-install -uy xbps
xbps-install -uy
# 4) 收尾:清孤儿、验证
xbps-remove -oy
xbps-install -un
xbps-query -L

4.2 试装一个软件的完整闭环

xbps-query -Rs figlet          # 远程搜索确认包名
xbps-install -n figlet         # 干跑看事务与体积
xbps-install -y figlet         # 实际安装
xbps-query -S figlet           # 查详情(含 install-date)
xbps-query -f figlet           # 看装了哪些文件
xbps-remove -yR figlet         # 连依赖移除(先 -nR 审过清单)
xbps-remove -OOy               # 清缓存

4.3 依赖影响评估与文件归属

xbps-query -x cowsay           # 它依赖谁
xbps-query -X perl             # 谁依赖它(删前必查)
xbps-query -o "/usr/bin/cow*"  # 反查文件属于哪个包
xbps-query -m                  # 本机手动安装清单
xbps-query -O                  # 孤儿清单

4.4 锁定关键包防升级

xbps-pkgdb -m hold xbps        # 锁定
xbps-query -H                  # 验证:xbps-0.60.7_1
xbps-pkgdb -m unhold xbps      # 解锁

五、注意事项与常见问题

Q1:全新机器 xbps-install -y <pkg> 报 Package 'xxx' not found in repository pool.(退出码 2) 没有同步过索引。先 xbps-install -S。带 -R 的远程查询在此状态下静默失败(退出码 95),没有任何提示,更隐蔽。

Q2:xbps-install -S 报 SSL certificate subject doesn't match host alpha.de.repo.voidlinux.org 和 Operation not permitted(退出码 95) 老镜像内置源已失效。在 /etc/xbps.d/00-repository-main.conf 写 repository=https://repo-default.voidlinux.org/current 覆盖(务必同名文件覆盖,而不是追加新源文件),再 -S。

Q3:xbps-install -uy 报 The 'xbps' package must be updated, please run `xbps-install -u xbps` (退出码 16) XBPS 自升级门禁。老系统跨大版本升级前必须先 xbps-install -uy xbps。

Q4:脚本里执行到安装就 Aborting! 非交互环境读不到 Do you want to continue? 的输入。所有自动化命令加 -y。

Q5:新源上装新包报依赖不满足(如 tree 2.2.1 要求 glibc>=2.39_1) 老系统 + 新仓库的组合问题。先完成 2.2.4 的全量升级把基础库带上去,再装新包。

Q6:ls /var/db/xbps/ | grep repodata 找不到索引文件? repodata 在按源 URL 转义命名的子目录里(/var/db/xbps/https___<域名>_<路径>/x86_64-repodata),不在顶层。

Q7:xbps-query -o /usr/bin/cow* 报 ERROR: xbps-query: too many arguments glob 被 shell 先展开了。模式必须加引号;且 -o 只匹配完整路径,纯文件名模式(-o "cowthink")不命中。

Q8:xbps-query -S <包名> 没有任何输出? 对未安装包 -S(默认模式)静默退出(退出码 2)。查远程包加 -R:xbps-query -R -S <pkg>。移除后再查同理。

Q9:--property=-、--cat= 输出为空? 两者都可能是"静默不生效/文件不存在":--property=-(stdin 传属性清单)在 0.60.7 实测无输出,请用逗号分隔形式;--cat 对包内不存在的文件不报错,先用 -f 确认路径。-p 清单里写错属性名也会被静默跳过。

Q10:重复安装已装的包会出错吗? 报 ERROR: Package 'xxx' already installed. 但退出码 0,幂等无害。

Q11:xbps-query -L 输出为空? 同步未成功完成时源不会注册进来(2.2.2 阶段实测)。换源修复并成功 -S 后出现 14823 https://repo-default.voidlinux.org/current (RSA signed)。

Q12:代理网络瞬断时安装报什么错? 实测报 SSL_connect returned 5 + ERROR: [trans] failed to download 'xxx' signature ...: Operation not permitted、ERROR: Transaction failed!(退出码 2)。属网络层问题,恢复后重跑即可;XBPS 事务是原子的,失败不会留下半安装状态。

Q13:ignorepkg 怎么不生效? 它不拦截显式安装(3.5.2 实测),作用域是依赖解析与批量升级中的自动跳过。

六、参考链接