apt 还是 apt-get
在终端里手敲用 apt,写脚本用 apt-get 和 apt-cache。
apt(8) 手册页写得很明白:apt 是给终端用户设计的,不同版本之间行为可能变化;即使尽量不破坏兼容,如果某个改动对交互使用有好处,也不保证兼容。apt-get、apt-cache 的功能 apt 都有,apt 只是改了一些选项的默认值,而老命令更注重向后兼容,所以脚本里应该用它们。
把 apt 的输出接到管道里时,它自己也会提醒:
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
看到这条,先检查是不是在脚本里调了 apt。
更新与升级
sudo apt update
sudo apt upgrade
update 只下载各个软件源的包索引,不装也不删任何软件。upgrade 才真正升级已安装的包,手册页对它有两条限定:为了满足依赖,它可以装新包;但已安装的包永远不会被它移除。如果某个包的升级要求移除另一个已安装的包,这个包就不升级。
full-upgrade 做 upgrade 能做的一切,另外在整体升级需要时会移除已安装的包。所以两者的区别只有一条:full-upgrade 可能删包,upgrade 不会。
升级之前看看有哪些包待升:
apt list --upgradable
没有待升级的包时只输出 Listing...。
装包之前先模拟
加上 -s(simulate)可以不改动系统,只看 apt 打算做什么:
apt install -s htop
输出末尾有一行汇总,例如 Upgrading: 0, Installing: 1, Removing: 0, Not Upgrading: 0,前面用 Inst、Remv 开头的行列出具体动作。涉及移除或大批量升级的操作,先模拟一遍,重点看 Removing 是不是你预期的数字。
手册页还介绍了几种写法:
- 包名可以是精确名称,也可以是正则或 glob,一个随手写的通配符可能匹配到很多包,模拟能帮你提前发现。
包名=版本号指定版本,包名/发行代号从某个发行版取版本。- 在包名后面加
+表示安装,加-表示移除。我在容器里试过apt install -s cron htop-:汇总里出现了Removing: 1,即 htop。
查询
apt show htop
apt policy htop
apt search 关键词
dpkg -S /usr/bin/htop
apt show 给出版本、优先级、分类、来源、维护者和安装大小等字段,手册页提醒可以在移除一个包之前先看这些信息。apt policy 显示已装版本、Candidate(候选版本)和来源优先级,怀疑装到的版本不对时,用它看版本来自哪个源。apt search 按正则搜索包列表,想按文件反查包,手册页建议用 apt-file。dpkg -S 回答“这个文件属于哪个包”,实测 dpkg -S /usr/bin/htop 输出 htop: /usr/bin/htop。
apt list 有三个常用选项:--installed、--upgradeable(--upgradable 同样可用)和 --all-versions。
remove、purge 和 autoremove
remove 删掉包的程序文件,但会留下你改过的配置文件,这样误删后重装就能恢复原样。purge 把这些残留也清掉,对已经 remove 过的包同样可以执行。手册页特别说明:它不会动你家目录里的数据和配置。
用 cron 在容器里验证过:
sudo apt remove cron
dpkg -l cron
状态列是 rc(已移除,配置文件还在);再执行 sudo apt purge cron,状态变成 un(未安装,无残留)。
autoremove 移除“为了满足依赖而自动装上、现在已经没人需要”的包。你明确安装的包不会被它提议移除,但手册页提醒要看一眼列表,免得误删用惯的软件。如果某个自动装上的包你想留下,用 apt-mark manual 包名 标成手动安装。执行前先模拟:
apt autoremove -s
锁定版本
sudo apt-mark hold htop
apt-mark showhold
sudo apt-mark unhold htop
分别是锁定、查看已锁定的包、解除锁定,输出依次是 htop set on hold.、htop、Canceled hold on htop.。
事务历史和撤销
APT 3.x 新增了一组按事务管理的命令,很多旧教程里没有。我在 Ubuntu 26.04.1 LTS 的容器(apt 3.2.0)里验证了下面的用法,在你的机器上先用 apt --help 看有没有这些命令。
apt history-list
apt history-info 88
sudo apt -y history-undo 88
sudo apt -y history-redo 88
history-list 列出历史事务,每行有 ID、命令行、时间、动作和改动数;命令行会被截断,要看完整内容用 history-info。我这里 ID 88 是一次 apt-get install -y -qq htop,history-info 88 显示 Install htop:arm64 (3.4.1-5build2)。对它执行 history-undo,apt 移除了 htop,dpkg -l htop 找不到该包;再 history-redo 就重新装回来,状态是 ii。history-undo、history-redo、history-rollback 都需要 ID,不带的话报 Error: Incorrect usage, no ID was given.
撤销有边界。我对一条“重装 bash”的事务执行 history-undo,apt 列出将要移除 bash,警告 This should NOT be done unless you know exactly what you are doing!,最后拒绝执行:
Error: Essential packages were removed and -y was used without --allow-remove-essential.
涉及系统必需包的事务不会因为加了 -y 就被撤销。报错里提到的开关会放开这个保护,这一步不建议为了让命令通过而去加。
history-rollback 的说明是 “rollback transactions”,我没有实际执行过,不展开。无论 apt 版本新旧,/var/log/apt/history.log 都记着每次操作的时间、命令行和包的版本变化,读它可能需要 sudo。
why 和 why-not
手册页对这两个命令的定义:apt why 包名 说明一个已安装的包为什么会被装上。自动安装的包能得到合理的解释,手动安装的包不会给出别的原因;包没有安装,则查不到原因。apt why-not 包名 说明一个包为什么被判定无法安装,不一定每次都有结果。两个命令只接受一个包名。
在我的最小容器里它们的输出很简单,比如 apt why htop 是 htop:arm64 is selected for install,对一个没装的包是 is undecided。依赖关系复杂的机器上输出会更有信息量,这时 why 能帮你判断某个包能不能放心 autoremove。
软件源
Ubuntu 26.04.1 的软件源是 /etc/apt/sources.list.d/ubuntu.sources,deb822 格式,文件里有大量 ## 开头的注释解释各个字段。
sudo apt edit-sources
用你偏好的编辑器编辑软件源文件,并做基本检查。手册页把它标为 work-in-progress,也就是还没定型。命令列表里还有 apt modernize-sources,把旧式 .list 文件改成 .sources 文件,我没有实际运行它,使用前先看 man apt。
几个常见情况
- 升级后有些包没动: 它们的升级需要移除别的已安装包,
upgrade不做这种升级。先看apt list --upgradable,确认后再用full-upgrade。 - remove 之后
dpkg -l里还有这个包: 状态rc说明配置文件残留,purge清掉。 - 想撤销刚才的安装: 有
history命令就用history-undo,没有就按history.log里记的包名手动remove。




