apt升级软件包
声明
GLM-5.2输出原文
为什么写这个?
用apt做了一次常规升级,发现会升级系统组件和nvidia驱动,不会出现只升级NV驱动而不更新系统额外组件导致网卡驱动不更新的问题,所以直接更新了。
但是重启后NV掉驱动了。
让GLM读了一遍操作了才发现NV驱动是kept back的!!!根本没更新。。。
一、apt update 到底在干什么
apt update 的唯一作用是下载并刷新本地软件包索引(即 /var/lib/apt/lists/ 下的一系列 Packages/Sources 文件),它对应的是 /etc/apt/sources.list 和 /etc/apt/sources.list.d/*.list 里配置的每一个仓库(包括 TUNA 镜像、Ubuntu 官方 security、PPA、第三方源等)。
- 它不会安装、升级或删除任何软件,只是让系统知道”每个包当前在仓库里的最新版本是多少”。
- 如果不先
apt update,apt upgrade看到的是过时的索引,可能漏掉新版本或报404 Not Found(旧版本已从镜像下架)。 - 输出里的
Hit(索引无变化)、Get(下载了新索引)、Ign(忽略)就对应每个仓库的刷新结果。
二、一组与升级相关的命令对比
| 命令 | 作用 | 是否装新依赖 | 是否删包 | 典型用途 |
|---|---|---|---|---|
apt update |
刷新本地软件包索引 | 否 | 否 | 每次升级前必先执行 |
apt upgrade |
升级已安装包,保守 | 否 | 否 | 普通安全更新;遇到依赖变更会 kept back |
apt full-upgrade |
升级 + 处理依赖变更 | 是 | 必要时是 | 内核/NVIDIA/大版本升级;等同于旧版 dist-upgrade |
apt-get upgrade |
老式,绝不装新依赖 | 否 | 否 | 脚本中常用,输出更稳定 |
apt-get dist-upgrade |
老式,等于 apt full-upgrade |
是 | 必要时是 | 脚本/服务器环境 |
apt install <pkg> |
安装或升级指定包 | 是 | 否 | 精确控制升级某个包 |
apt autoremove |
删除被自动安装且不再被需要的包 | 否 | 是 | 清理旧内核模块、旧依赖 |
apt autoclean |
清理 /var/cache/apt/archives 中已过期的 .deb |
— | — | 释放缓存 |
apt clean |
清空全部 .deb 缓存 | — | — | 释放更多磁盘 |
apt-mark hold <pkg> |
锁定包不升级 | — | — | 临时冻结某个包版本 |
apt-mark showhold |
查看被锁定的包 | — | — | 排查 kept back 是否人为 |
注意 apt(新命令)和 apt-get(老命令)在 upgrade 上的行为不完全一样:apt upgrade 会安装新依赖,而 apt-get upgrade 严格不装任何新包。这也是为什么社区常说”脚本里用 apt-get,交互终端用 apt“。 |
三、为什么会出现 “kept back”(保留)
这是你这次问题的核心。apt upgrade 的设计原则是绝不主动安装系统里原本不存在的新包、也绝不删除已存在的包。当一个包的新版本引入了新的依赖(仓库里多了一个原本不存在的包名),apt upgrade 就会把这个包列入 “kept back”,而不是强行装上。
你这次的实际情况:
linux-modules-nvidia-595-open-generic-hwe-22.04的新版本6.8.0-136...+1依赖一个新包linux-modules-nvidia-595-open-6.8.0-136-generic(专门给 6.8.0-136 内核编译的模块包),这个包在你系统里之前不存在。apt upgrade不愿意”主动装新包”,于是把整个 NVIDIA 系列全部 kept back,只升级了内核。- 结果:内核进了 6.8.0-136,但
/lib/modules/6.8.0-136-generic/里没有nvidia.ko,重启后 GPU 失联。
要区分两种”没被升级”的情况: - kept back(依赖关系变更引起)→
apt full-upgrade可解。 - hold(你或脚本用
apt-mark hold手动锁定)→ 必须apt-mark unhold才能升级,full-upgrade也绕不过去。用apt-mark showhold可以一眼区分。
四、HWE 内核与 NVIDIA 驱动的联动机制
Ubuntu 22.04 用的是 HWE(Hardware Enablement)内核,它会在 LTS 周期内滚动更新大版本内核(你从 6.8.0-124 → 6.8.0-136 就是 HWE 滚动)。NVIDIA 驱动在 Ubuntu 仓库里有两种打包方式,联动机制不同:
- 预编译签名模块(你现在用的
nvidia-driver-595-open+linux-modules-nvidia-595-open-generic-hwe-22.04):每个内核 ABI 都对应一个独立的模块包(如linux-modules-nvidia-595-open-6.8.0-136-generic),由 meta 包linux-modules-nvidia-595-open-generic-hwe-22.04拉进来。内核一变,meta 包就要跟着升级,否则模块断链。 - DKMS 方式(
nvidia-kernel-source-595-open配合dkms):装新内核头文件后会自动在本地重新编译nvidia.ko,不需要每个内核一个独立包,但需要linux-headers-$(uname -r)和编译工具链齐全。
你的输出里两种痕迹都有(nvidia-kernel-source-595-open在装,但实际靠的是预编译模块包),关键判据是ls /lib/modules/$(uname -r)/里有没有nvidia*.ko——没有就是断链。
五、常见”升级翻车”场景与排查
| 场景 | 现象 | 排查命令 |
|---|---|---|
| 内核与 NVIDIA 模块断链 | 重启后 nvidia-smi 失败,SSH 正常 |
ls /lib/modules/$(uname -r)/、dpkg -l | grep linux-modules-nvidia |
| 旧内核未清理占满 /boot | apt 报 “No space left on device” |
df -h /boot、dpkg -l | grep linux-image、apt autoremove |
| 第三方 PPA 引入不兼容依赖 | 升级后桌面/CUDA 异常 | apt list --upgradable、ppa-purge、检查 /etc/apt/sources.list.d/ |
| 镜像源同步延迟导致版本不一致 | apt update 报 hash mismatch / 404 |
换源、apt clean、等待镜像同步 |
linux-firmware 升级后网卡/显卡异常 |
设备未识别 | dmesg、回退固件包 |
| phased updates(分阶段推送) | 同样的包在别的机器能升级,你的不行 | apt list --upgradable -a 看是否 (phased XX%) |
| 误删依赖导致 meta 包丢失 | 以后内核升级不再自动带驱动 | apt install --install-recommends linux-modules-nvidia-595-open-generic-hwe-22.04 |
六、推荐的安全更新工作流
把下面这套顺序作为习惯,能避免绝大多数升级翻车:
1 | |
几个配套但容易混淆的清理命令:
apt autoremove:删掉”当初作为依赖被装进来、现在没人依赖了”的包——比如旧内核的linux-modules-nvidia-595-open-6.8.0-117-generic这类。升级内核后跑一下很有用,但要先看清它要删什么,别误删正在用的内核。apt autoclean:只删缓存里已经无法下载的旧.deb。apt clean:把/var/cache/apt/archives/清空,磁盘紧张时用。
一句话收束:在有 NVIDIA / CUDA / 自编译内核模块的机器上,把 apt upgrade 习惯换成 apt full-upgrade,并且每次升级前都看一眼 apt list --upgradable 里的 kept back 列表——这次的问题就不会再出现第二次。