apt-cache 命令详解与参数实测(Ubuntu 22.04)
apt-cache 命令逐参数实测:gencaches 与 stats 缓存统计全字段解读、pkgnames、search 与 --names-only、show 与 apt show 同源对照、policy 版本优先级 500/100 与多版本表、depends/rdepends 正反向依赖、madison 版本表、unmet 未满足依赖检查,全部回显在 Ubuntu 22.04(apt 2.4.14)实测通过。
apt-cache 命令详解与参数实测(Ubuntu 22.04)
目标:全面掌握 apt-cache 的每一个常用子命令——gencaches 与 stats 的缓存统计全字段解读、pkgnames 包名清单、search 与 --names-only 检索、show 与 apt show 的同源对照、policy 版本优先级(500/100 与多版本表)、depends/rdepends 正反向依赖、madison 版本表、unmet 未满足依赖检查,全部命令与回显已在 Ubuntu 22.04(apt 2.4.14)实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- APT 版本:apt-cache 2.4.14(apt / apt-get / apt-cache 三件套同版本)
- 数据来源:
/var/lib/apt/lists/下的本地索引缓存(由 apt update / apt-get update 刷新);本机 dpkg 数据库/var/lib/dpkg/status - 演示包:sl 5.02-1、tree 2.0.2-1、cowsay 3.03+dfsg2-8、unzip 6.0-26ubuntu3.2(仓库真实版本)
- apt-cache 是只读查询工具:不联网、不改系统,全部信息来自本地缓存,因此所有子命令普通用户即可执行
💡 技术拓展:APR 家族分工——apt-get 负责「变更」、apt-cache 负责「查询」、apt 是两者的整合壳。本篇聚焦 apt-cache 的查询能力;姊妹篇另有 apt 与 apt-get 的逐参数实测。另一个常见组合是 apt-file(按文件名反查归属包),它需要单独安装并维护文件索引,apt-cache 没有按文件查包的能力(见 3.7 节末尾对比)。
二、命令概览
2.1 语法与测试数据
apt-cache 的基本语法是 apt-cache [options] command [package ...]:command 为查询子命令,package 为包名或正则(search 支持 POSIX 正则)。它完全基于本地缓存工作,官方 --help 原文说明其特性:It works exclusively on the data acquired into the local cache via the 'update' command of e.g. apt-get.——太久不 update 结果就可能过时,但换来的优点是离线可用。
本篇演示围绕以下包展开,先看仓库中的真实版本表:
$ apt-cache madison sl tree cowsay
sl | 5.02-1 | http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
tree | 2.0.2-1 | http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
cowsay | 3.03+dfsg2-8 | http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
2.2 --help 全量输出
apt-cache --help 全量回显(逐行照抄):
$ apt-cache --help
apt 2.4.14 (amd64)
Usage: apt-cache [options] command
apt-cache [options] show pkg1 [pkg2 ...]
apt-cache queries and displays available information about installed
and installable packages. It works exclusively on the data acquired
into the local cache via the 'update' command of e.g. apt-get. The
displayed information may therefore be outdated if the last update was
too long ago, but in exchange apt-cache works independently of the
availability of the configured sources (e.g. offline).
Most used commands:
showsrc - Show source records
search - Search the package list for a regex pattern
depends - Show raw dependency information for a package
rdepends - Show reverse dependency information for a package
show - Show a readable record for the package
pkgnames - List the names of all packages in the system
policy - Show policy settings
See apt-cache(8) for more information about the available commands.
Configuration options and syntax is detailed in apt.conf(5).
Information about how to configure sources can be found in sources.list(5).
Package and version choices can be expressed via apt_preferences(5).
Security details are available in apt-secure(8).
2.3 版本信息
$ apt-cache --version
apt 2.4.14 (amd64)
三、参数逐项实测
3.1 gencaches:构建/刷新缓存
gencaches 显式触发缓存构建(把 lists 索引与 dpkg 状态合并为 apt 内部缓存)。日常由各查询子命令自动触发,手动执行常用于排障「缓存疑似损坏/未初始化」的场景:
$ apt-cache gencaches; echo rc=$?
Reading package lists...
rc=0
输出极简:仅一行进度提示,rc=0 即缓存就绪。
💡 要点:
gencaches日常无需手动调用——所有查询子命令发现缓存缺失都会自动构建。它真正的用武之地是排障:apt update后查询仍报「找不到包」时,先手动apt-cache gencaches重建缓存再查,能排除「索引已更新但内部缓存未刷新」的状态不同步。
3.2 stats:缓存统计全输出解读
stats 打印内部缓存的统计画像,是评估索引规模与缓存健康度的最直接手段:
$ apt-cache stats
Total package names: 168967 (4731 k)
Total package structures: 156619 (6891 k)
Normal packages: 120469
Pure virtual packages: 2034
Single virtual packages: 22283
Mixed virtual packages: 483
Missing: 11350
Total distinct versions: 134879 (11.9 M)
Total distinct descriptions: 134879 (3237 k)
Total dependencies: 696909/149243 (16.3 M)
Total ver/file relations: 63016 (1512 k)
Total Desc/File relations: 3807 (91.4 k)
Total Provides mappings: 73680 (1768 k)
Total globbed strings: 325573 (9160 k)
Total slack space: 91.0 k
Total space accounted for: 57.3 M
Total buckets in PkgHashTable: 196613
Unused: 88811
Used: 107802
Utilization: 54.8295%
Average entries: 1.45284
Longest: 18
Shortest: 1
Total buckets in GrpHashTable: 196613
Unused: 83284
Used: 113329
Utilization: 57.6406%
Average entries: 1.49094
Longest: 10
Shortest: 1
逐块解读:
Total package names: 168967:缓存中不重复的包名总数(含虚拟名),括号内是占用量。Total package structures: 156619:包结构体数量,其下的四行是构成——Normal(真实包)120469、Pure virtual(纯虚拟名,如awk只是提供者集合)2034、Single virtual(历史上是真实包、后变为虚拟)22283、Mixed virtual(既是真实包又可作虚拟名)483;Missing: 11350是被引用但缓存中无记录的名字。Total distinct versions / descriptions:去重后的版本与描述条目数。Total dependencies: 696909/149243:依赖关系总数/去重后总数——依赖网络规模一目了然。Total ver/file relations、Desc/File relations、Provides mappings:版本-文件、描述-文件与 Provides 映射的条目量。- 两个哈希表(PkgHashTable/GrpHashTable)的桶数、利用率与链长是内部索引的体检指标,利用率 50%
60%、平均链长 1.41.5 属正常水平。 - 括号里的
57.3 M是全部缓存数据结构占用的内存量级。
💡 要点:
stats是只读体检,数值健康即可跳过;真正要盯的是Total distinct versions与Total package names的比值——比率异常膨胀通常意味着源里混入了大量多版本包(如 backports/第三方源)。哈希表利用率长期低于 30% 说明缓存数据量与内存占用不匹配,可考虑清理多余的源。
3.3 pkgnames:包名清单
不带参数列出缓存中全部包名,可先看规模再抽样:
$ apt-cache pkgnames | wc -l
120952
$ apt-cache pkgnames | head -5
linux-modules-nvidia-470-server-5.15.0-1038-intel-iotg
lib32stdc++-11-dev-s390x-cross
linux-modules-nvidia-565-server-open-5.15.0-141-lowlatency
linux-objects-nvidia-535-5.15.0-1054-gcp
bazel-bootstrap
注意 120952 与 stats 的 Total package names: 168967 不是同一口径:pkgnames 只列「可作为安装目标」的真实/可用名,stats 的总数含虚拟名与 Missing 引用。带上前缀参数则做前缀补全(列出所有以该前缀开头的包名):
$ apt-cache pkgnames sl | head -10
slic3r-prusa
slang-gdbm
slashem
slurmdbd
slowhttptest
sludge-devkit
slashem-gtk
slinkwatch
slang-xfig
slurm-wlm-doc
(输出节选,pkgnames sl 实测共 75 行,含 sl、slapd、slurm、slim、slirp 等。)pkgnames 的输出顺序是哈希表顺序而非字母序,所以看到的第一行是 nvidia 内核模块也不奇怪;要有序结果请自行 sort。
💡 要点:
pkgnames 前缀是命令行补全的底层实现之一(bash-completion 调用它列候选)。注意它做前缀匹配而非子串匹配——搜「包名包含 nginx」要用apt-cache search --names-only nginx,两者口径不同别混用。
3.4 search:检索软件包
按关键词检索包名与描述(支持 POSIX 正则),输出格式为 包名 - 一行描述:
$ apt-cache search cowsay
cowsay - configurable talking cow
cowsay-off - configurable talking cow (offensive cows)
xcowsay - Graphical configurable talking cow
全文检索按描述词命中(cowsay 系列的描述都含 talking cow):
$ apt-cache search 'talking cow'
cowsay - configurable talking cow
cowsay-off - configurable talking cow (offensive cows)
xcowsay - Graphical configurable talking cow
反过来,换一个描述里没有的词(如 locomotive)就一无所获——apt-cache search 不做模糊语义匹配:
$ apt-cache search locomotive
--names-only 把匹配范围限制在包名,配合正则锚点可做精确查询(^sl$ 只命中名为 sl 的包):
$ apt-cache search --names-only '^sl$'
sl - Correct you if you type `sl' by mistake
$ apt-cache search --names-only cowsay
cowsay - configurable talking cow
cowsay-off - configurable talking cow (offensive cows)
xcowsay - Graphical configurable talking cow
与 apt search 对照(同一条查询):apt 输出带套件/版本/架构头行与相关度排序(Sorting...),apt-cache 输出原始的 包名 - 描述 行、顺序跟随缓存索引:
$ apt search cowsay
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Sorting...
Full Text Search...
cowsay/jammy 3.03+dfsg2-8 all
configurable talking cow
cowsay-off/jammy 3.03+dfsg2-8 all
configurable talking cow (offensive cows)
xcowsay/jammy 1.6-1 amd64
Graphical configurable talking cow
💡 要点:两者查询同一份缓存;要「像人一样翻结果」用 apt search(排序+版本信息),要「像脚本一样解析」用 apt-cache search(行格式固定,按
-切两列)。
3.5 show:包详情(与 apt show 同源对照)
apt-cache show 包名 输出该包在索引中的原始记录(Debian control 字段全集):
$ apt-cache show sl
Package: sl
Architecture: amd64
Version: 5.02-1
Priority: optional
Section: universe/games
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Markus Frosch <lazyfrosch@debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 59
Depends: libc6 (>= 2.2.5), libncurses6 (>= 6), libtinfo6 (>= 6)
Filename: pool/universe/s/sl/sl_5.02-1_amd64.deb
Size: 12708
MD5sum: a9d3404fd92fb694a069f669cf729e02
SHA1: 9d51f44449d64521ca8c903e4d70bd983798eb39
SHA256: aeda5a0e5f2ed185078e7819b9a6176eb6b09190d4b58dc46e049d9f01fa0ea9
SHA512: 99a94cecd3001005f90fbf0e958f9c2ee87fb52c0a1733f59cdd9071f5e52f1fda1dc81695b5e72c117f47bb88347bff349e35cf4a805f259cbc4d9d515744fe
Homepage: https://github.com/mtoyoda/sl
Description: Correct you if you type `sl' by mistake
Description-md5: 64964faf22f36fbd8983fb5015010c0b
同一包的 apt show sl 输出(同一缓存渲染,字段做了人本化处理):
$ apt show sl
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Package: sl
Version: 5.02-1
Priority: optional
Section: universe/games
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Markus Frosch <lazyfrosch@debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 60.4 kB
Depends: libc6 (>= 2.2.5), libncurses6 (>= 6), libtinfo6 (>= 6)
Homepage: https://github.com/mtoyoda/sl
Download-Size: 12.7 kB
APT-Sources: http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
Description: Correct you if you type `sl' by mistake
同源对照结论:核心字段(Version/Depends/Description)完全一致,差异在三处——apt show 把 Installed-Size: 59(KB 原始值)换成 60.4 kB 人读格式并新增 Download-Size 与 APT-Sources 行;apt-cache show 则保留 Filename(.deb 在池中的路径)、Size、MD5sum/SHA1/SHA256/SHA512、Description-md5 等原始校验字段,这些是脚本比对校验和、构造下载链接的原料。查不存在的包时两者同样报错但 apt-cache 带非零退出码:
$ apt-cache show demo-not-exist; echo rc=$?
E: No packages found
rc=100
💡 要点:脚本化取包信息优先选
apt-cache show(有退出码可判错、字段原始完整);apt show面向人读且对不存在包返回 rc=0,不适合做脚本断言。需要「字段→值」精确解析时,grep '^Version:'配合head -1即可从原始记录稳定取值。
3.6 policy:版本优先级解读(重点)
policy 包名 回答三个问题:装了什么(Installed)、会装哪个(Candidate)、还有哪些版本可选(Version table)。未安装时 Installed 显示 (none):
$ apt-cache policy sl
sl:
Installed: (none)
Candidate: 5.02-1
Version table:
5.02-1 500
500 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
$ apt-cache policy tree
tree:
Installed: (none)
Candidate: 2.0.2-1
Version table:
2.0.2-1 500
500 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
安装后再看(版本表出现 *** 标记与 dpkg 状态行):
$ apt-cache policy sl
sl:
Installed: 5.02-1
Candidate: 5.02-1
Version table:
*** 5.02-1 500
500 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
100 /var/lib/dpkg/status
逐行解读:
*** 5.02-1 500:***标记已安装版本;行尾数字 500 是该版本所属源的 pin 优先级。500 http://archive.ubuntu.com/ubuntu jammy/universe ...:该版本来自优先级 500 的仓库(archive.ubuntu.com 的常规套件默认 500)。100 /var/lib/dpkg/status:已安装记录本身也参与候选比较,优先级 100——这就是「已装的旧版本不会被仓库里的同版本号之外的新源轻易顶掉」的机制基础。
unzip 的输出更能说明多版本场景:候选 6.0-26ubuntu3.2 来自 jammy-updates(500),历史版本分属 jammy-security(500)与 jammy(500),已安装版本另有 100 的 status 记录:
$ apt-cache policy unzip
unzip:
Installed: 6.0-26ubuntu3.2
Candidate: 6.0-26ubuntu3.2
Version table:
*** 6.0-26ubuntu3.2 500
500 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages
100 /var/lib/dpkg/status
6.0-26ubuntu3.1 500
500 http://security.ubuntu.com/ubuntu jammy-security/main amd64 Packages
6.0-26ubuntu3 500
500 http://archive.ubuntu.com/ubuntu jammy/main amd64 Packages
多个同优先级版本时,Candidate 取版本号最高者;若把某源 pin 成更高优先级(如 1001),低版本也能反向覆盖已装版本(降级场景,需配合 apt-get install --allow-downgrades)。
不带包名的 apt-cache policy 打印全局源优先级清单(Package files: 列出每个源组件的优先级与元数据指纹,Pinned packages: 列出手工 pin 项,本机为空):
$ apt-cache policy
Package files:
100 /var/lib/dpkg/status
release a=now
500 http://security.ubuntu.com/ubuntu jammy-security/multiverse amd64 Packages
release v=22.04,o=Ubuntu,a=jammy-security,n=jammy,l=Ubuntu,c=multiverse,b=amd64
origin security.ubuntu.com
500 http://security.ubuntu.com/ubuntu jammy-security/universe amd64 Packages
release v=22.04,o=Ubuntu,a=jammy-security,n=jammy,l=Ubuntu,c=universe,b=amd64
origin security.ubuntu.com
500 http://security.ubuntu.com/ubuntu jammy-security/restricted amd64 Packages
release v=22.04,o=Ubuntu,a=jammy-security,n=jammy,l=Ubuntu,c=restricted,b=amd64
origin security.ubuntu.com
500 http://security.ubuntu.com/ubuntu jammy-security/main amd64 Packages
release v=22.04,o=Ubuntu,a=jammy-security,n=jammy,l=Ubuntu,c=main,b=amd64
origin security.ubuntu.com
100 http://archive.ubuntu.com/ubuntu jammy-backports/universe amd64 Packages
release v=22.04,o=Ubuntu,a=jammy-backports,n=jammy,l=Ubuntu,c=universe,b=amd64
origin archive.ubuntu.com
100 http://archive.ubuntu.com/ubuntu jammy-backports/main amd64 Packages
release v=22.04,o=Ubuntu,a=jammy-backports,n=jammy,l=Ubuntu,c=main,b=amd64
origin archive.ubuntu.com
500 http://archive.ubuntu.com/ubuntu jammy-updates/multiverse amd64 Packages
release v=22.04,o=Ubuntu,a=jammy-updates,n=jammy,l=Ubuntu,c=multiverse,b=amd64
origin archive.ubuntu.com
500 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages
release v=22.04,o=Ubuntu,a=jammy-updates,n=jammy,l=Ubuntu,c=universe,b=amd64
origin archive.ubuntu.com
500 http://archive.ubuntu.com/ubuntu jammy-updates/restricted amd64 Packages
release v=22.04,o=Ubuntu,a=jammy-updates,n=jammy,l=Ubuntu,c=restricted,b=amd64
origin archive.ubuntu.com
500 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages
release v=22.04,o=Ubuntu,a=jammy-updates,n=jammy,l=Ubuntu,c=main,b=amd64
origin archive.ubuntu.com
500 http://archive.ubuntu.com/ubuntu jammy/multiverse amd64 Packages
release v=22.04,o=Ubuntu,a=jammy,n=jammy,l=Ubuntu,c=multiverse,b=amd64
origin archive.ubuntu.com
500 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
release v=22.04,o=Ubuntu,a=jammy,n=jammy,l=Ubuntu,c=universe,b=amd64
origin archive.ubuntu.com
500 http://archive.ubuntu.com/ubuntu jammy/restricted amd64 Packages
release v=22.04,o=Ubuntu,a=jammy,n=jammy,l=Ubuntu,c=restricted,b=amd64
origin archive.ubuntu.com
500 http://archive.ubuntu.com/ubuntu jammy/main amd64 Packages
release v=22.04,o=Ubuntu,a=jammy,n=jammy,l=Ubuntu,c=main,b=amd64
origin archive.ubuntu.com
Pinned packages:
全局清单里能直接读到 Ubuntu 的默认 pin 策略:常规套件与 updates 是 500、backports 只有 100(所以 backports 的包默认不会被自动安装/升级)、本地 dpkg 状态是 100。release a=now 即「当前已安装集合」。查不存在的包时 policy 不报错也不输出,rc=0——这点与 show/madison 不同:
$ apt-cache policy demo-not-exist; echo rc=$?
rc=0
💡 要点:优先级记忆口诀——100=已安装,500=常规仓库(updates 同级),100=backports(默认不自动装),1000+ 允许降级。判断「为什么装的是这个版本」,
apt-cache policy 包名是第一现场。
3.7 depends / rdepends:正反向依赖
depends 列出正向依赖(含版本约束原样输出),cowsay 的输出还演示了虚拟包写法 <perl:any>:
$ apt-cache depends cowsay
cowsay
Depends: libtext-charwidth-perl
Depends: <perl:any>
perl
Suggests: filters
Suggests: cowsay-off
$ apt-cache depends sl
sl
Depends: libc6
Depends: libncurses6
Depends: libtinfo6
Depends: <perl:any> 表示依赖「任何架构提供的 perl」,缩进的下一行给出满足该虚拟名的真实包 perl。Suggests 只提示不安装,与 Recommends 的自动安装行为不同。
rdepends 反向查询「谁依赖我」,删包前评估影响面就靠它(libtext-charwidth-perl 被三个包依赖):
$ apt-cache rdepends libtext-charwidth-perl
libtext-charwidth-perl
Reverse Depends:
debconf-i18n
cowsay
libtext-wrapi18n-perl
底层库的反向依赖面很大,配合 head 截取(输出节选):
$ apt-cache rdepends libc6 | head -12
libc6
Reverse Depends:
libc6-dbg
wpagui
systemd-tests
systemd-standalone-tmpfiles
systemd-standalone-sysusers
systemd-journal-remote
systemd-coredump
ssh-askpass-gnome
slapd-contrib
qemu-user
💡 技术拓展:apt-cache 只能按包查依赖,不能按文件查归属。想问「/usr/bin/xxx 属于哪个包」需要 apt-file(
apt-file search 路径,需单独安装并 apt-file update 建文件索引);不装工具的临时替代是查 packages.ubuntu.com 或在已装包中用dpkg -S 路径。
3.8 madison:版本表
madison 以「包 | 版本 | 源」三列风格打印仓库中所有可见版本(名字来自 Debian 的 FTP 管理工具 madison),一行一个版本-源组合,是构造 pkg=version 安装命令前的标准查表动作:
$ apt-cache madison sl tree cowsay
sl | 5.02-1 | http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
tree | 2.0.2-1 | http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
cowsay | 3.03+dfsg2-8 | http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
unzip 这类多源多版本包会列出多行(同 apt-cache policy 的版本表一一对应,实测见 3.6)。查不存在的包时静默无输出、rc=0:
$ apt-cache madison demo-not-exist; echo rc=$?
rc=0
💡 要点:madison 输出适合机器解析(
|分隔),policy 输出适合人工解读(带优先级);两者数据同源,选哪个看场景。
3.9 unmet:未满足依赖检查
unmet 扫描缓存中全部包的依赖声明,列出「按当前源无法同时满足」的组合。输出量远超日常需要,务必节选使用:
$ apt-cache unmet | head -6
Package linux-modules-nvidia-580-server-open-5.15.0-160-lowlatency version 5.15.0-160.170+1 has an unmet dep:
Depends: nvidia-kernel-common-580-server (<= 580.95.05-1)
Package linux-modules-nvidia-535-open-5.15.0-1038-gcp version 5.15.0-1038.46+1 has an unmet dep:
Depends: nvidia-kernel-common-535 (<= 535.86.05-1)
Package linux-modules-nvidia-580-server-open-6.8.0-1046-gcp version 6.8.0-1046.49~22.04.1 has an unmet dep:
Depends: nvidia-kernel-common-580-server (<= 580.126.09-1)
$ apt-cache unmet | wc -l
26097
$ apt-cache unmet >/dev/null 2>&1; echo rc=$?
rc=0
解读:仓库里存在 26097 行的交叉「unmet」记录(大量是 nvidia 内核模块与驱动版本上限约束这类上游固有的版本错位),并不代表本机依赖损坏——本机状态用 apt-get check 检查。unmet 的价值在于审阅「特定包/特定源组合」的可行性,日常按需 grep 包名过滤即可。
💡 要点:记住分工——
unmet审的是仓库声明(全源层面的依赖冲突预览),apt-get check查的是本机实况(已装包的依赖自洽性)。评估「引入某个第三方源会不会打架」时用前者,装完东西后体检用后者,两者结论不互通。
四、实战示例
4.1 找包选型三连
search 定位 → show 看详情 → depends 评估依赖,三个只读命令串联:
apt-cache search 'talking cow'
apt-cache show cowsay | grep -E '^(Package|Version|Depends|Description)'
apt-cache depends cowsay
对应回显形态见 3.4/3.5/3.7:search 给候选清单,show 给版本与硬依赖,depends 给依赖树与建议包。
4.2 版本决策与精确安装
madison 查版本表 → policy 看优先级与已装状态 → 按版本安装:
apt-cache madison sl
apt-cache policy sl
apt-get install -y sl=5.02-1
madison/policy 的回显见 3.8/3.6;第三步的安装回显与版本约束说明见 apt-get 篇 3.5。
4.3 卸载影响面评估
删除底层库前的必做检查——先看谁还依赖它:
apt-cache rdepends libtext-charwidth-perl
dpkg -l | grep libtext-charwidth-perl
rdepends 输出的三个反向依赖(debconf-i18n、cowsay、libtext-wrapi18n-perl,见 3.7)说明它不能随手删;第二行确认本机是否实际安装。两条都清白才能进入 remove/purge 流程。
4.4 缓存健康诊断
update 后做一次统计体检,与历史基线对比:
apt-get update
apt-cache gencaches
apt-cache stats | head -6
apt-cache pkgnames | wc -l
stats 的包名/版本/依赖总量与 pkgnames 计数(回显见 3.1/3.2/3.3)若较基线骤降,通常意味着源配置或 update 出了问题;若 gencaches 报 E,先检查 /var/lib/apt/lists/ 是否被清空、再重跑 apt-get update。
五、注意事项与常见问题
Q1:apt-cache 和 apt search/show 到底什么关系? A:同一份缓存、同一个数据层。apt search/show 是 apt(8) 对同一缓存的人本化渲染(带排序、版本头行、WARNING),apt-cache 输出原始格式且契约稳定。apt(8) 手册原文:All features of apt(8) are available in dedicated APT tools like apt-get(8) and apt-cache(8) as well.——脚本解析选 apt-cache,人眼浏览选 apt。实测对照见 3.4/3.5。
Q2:policy 里的 500/100 是什么数字?
A:APT 的 pin 优先级(详见 apt_preferences(5)):100 是已安装包(/var/lib/dpkg/status)与 backports 套件的默认值;500 是常规仓库(含 jammy、jammy-updates)的默认值;990 通常对应 target-release;1001 以上允许降级安装。Candidate 的选取规则是在「优先级最高」的版本里取版本号最大者。本机各源的实际优先级清单用不带参数的 apt-cache policy 查看(实测见 3.6 全局清单)。
Q3:show 报 rc=100,policy 和 madison 却 rc=0?
A:实测行为差异——apt-cache show demo-not-exist 输出 E: No packages found 并返回 100;apt-cache policy demo-not-exist 与 apt-cache madison demo-not-exist 静默无输出但 rc=0(见 3.5/3.6/3.8 的对照)。脚本里判断「包是否存在」要用 show 的退出码,别用 policy/madison。
Q4:unmet 输出两万多行正常吗?
A:正常。它扫描的是缓存里全部包声明的依赖(含各源中大量互斥的版本上限组合,如 nvidia 内核模块与驱动版本错位),并不反映本机实际状态。本机完整性检查用 apt-get check;unmet 通常配合 grep 包名 定点审阅。
Q5:stats 的 168967 个包名和 pkgnames 的 120952 行对不上?
A:口径不同。stats 的 Total package names 计入虚拟名与 Missing 引用(其下四行可见:Normal 120469 + Pure virtual 2034 + Single virtual 22283 + Mixed virtual 483,另有 Missing 11350);pkgnames 只列出可作为安装目标的可用名。两者都真实,用途不同——评估缓存规模看 stats,枚举可安装包看 pkgnames。
Q6:apt-cache 的结果多久会过期?
A:取决于最后一次 apt-get update。--help 原文说明它 works exclusively on the data acquired into the local cache,且 works independently of the availability of the configured sources (e.g. offline)——断网也能查,代价是「查到的版本」是缓存时点的快照。重要变更前先 update 再查。
Q7:能查本地已安装但源里没有的包吗? A:能。apt-cache 的数据层包含 dpkg 状态(policy 的 100 /var/lib/dpkg/status 行),已安装包即使已从源下架,policy 仍显示 Installed 与其 status 记录。这也是排障「幽灵包」(装过但源里找不到)的第一入口。
六、参考链接
- apt-cache(8) 手册(Ubuntu 22.04 jammy 版):https://manpages.ubuntu.com/manpages/jammy/en/man8/apt-cache.8.html
- apt_preferences(5) 优先级机制(500/100 详解):https://manpages.ubuntu.com/manpages/jammy/en/man5/apt_preferences.5.html
- apt(8) 手册:https://manpages.ubuntu.com/manpages/jammy/en/man8/apt.8.html
- apt-get(8) 手册:https://manpages.ubuntu.com/manpages/jammy/en/man8/apt-get.8.html
- sources.list(5) 软件源配置:https://manpages.ubuntu.com/manpages/jammy/en/man5/sources.list.5.html
- apt-file(按文件反查归属包):https://manpages.ubuntu.com/manpages/jammy/en/man1/apt-file.1.html
- Debian Wiki PackageManagement:https://wiki.debian.org/PackageManagement