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 自升级门禁、依赖版本门槛等真实排障全程。
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 实测),作用域是依赖解析与批量升级中的自动跳过。
六、参考链接
- XBPS 源码仓库:https://github.com/void-linux/xbps
- Void Linux 手册 XBPS 章节:https://docs.voidlinux.org/xbps/index.html
- 手册页:
xbps-install(1)、xbps-query(1)、xbps-remove(1)、xbps-reconfigure(1)、xbps-pkgdb(1)、xbps.d(5) - 官方主源:https://repo-default.voidlinux.org/current/
- 上海交通大学镜像(本文对照用):https://mirror.sjtu.edu.cn/voidlinux/
- 本专栏姊妹篇:sv 命令详解与参数实测(Void Linux)——runit 服务管理