为什么Ubuntu在删除旧内核时不清理掉旧的内核模块文件(位于/lib/modules目录下)呢?

今天我注意到目录/lib/modules仍然保留了之前安装的内核的所有目录,如下所示:
$ ls /lib/modules
5.4.0-29-generic  5.4.0-31-generic  5.4.0-33-generic  5.4.0-37-generic  5.4.0-39-generic
5.4.0-40-generic  5.4.0-42-generic  5.4.0-45-generic  5.4.0-47-generic  5.4.0-48-generic
...  etc.

在这些目录中,剩下了以下文件(适用于Intel/AMD系统):
$ ls -l
-rw-r--r--  1 root 143K 2022-04-28 18:36 modules.alias
-rw-r--r--  1 root 154K 2022-04-28 18:36 modules.alias.bin
-rw-r--r--  1 root 8.0K 2022-04-08 10:44 modules.builtin
-rw-r--r--  1 root  25K 2022-04-28 18:36 modules.builtin.alias.bin
-rw-r--r--  1 root  11K 2022-04-28 18:36 modules.builtin.bin
-rw-r--r--  1 root  63K 2022-04-08 10:44 modules.builtin.modinfo
-rw-r--r--  1 root  85K 2022-04-28 18:36 modules.dep
-rw-r--r--  1 root 123K 2022-04-28 18:36 modules.dep.bin
-rw-r--r--  1 root  268 2022-04-28 18:36 modules.devname
-rw-r--r--  1 root 215K 2022-04-08 10:44 modules.order
-rw-r--r--  1 root  489 2022-04-28 18:36 modules.softdep
-rw-r--r--  1 root 279K 2022-04-28 18:36 modules.symbols
-rw-r--r--  1 root 326K 2022-04-28 18:36 modules.symbols.bin

而对于树莓派(注意尺寸的差异):
-rw-r--r--  1 root 859K 2022-04-25 17:31 modules.alias
-rw-r--r--  1 root 893K 2022-04-25 17:31 modules.alias.bin
-rw-r--r--  1 root  11K 2022-04-04 13:33 modules.builtin
-rw-r--r--  1 root  27K 2022-04-25 17:31 modules.builtin.alias.bin
-rw-r--r--  1 root  14K 2022-04-25 17:31 modules.builtin.bin
-rw-r--r--  1 root  84K 2022-04-04 13:33 modules.builtin.modinfo
-rw-r--r--  1 root 399K 2022-04-25 17:31 modules.dep
-rw-r--r--  1 root 548K 2022-04-25 17:31 modules.dep.bin
-rw-r--r--  1 root  250 2022-04-25 17:31 modules.devname
-rw-r--r--  1 root 209K 2022-04-04 13:33 modules.order
-rw-r--r--  1 root  950 2022-04-25 17:31 modules.softdep
-rw-r--r--  1 root 354K 2022-04-25 17:31 modules.symbols
-rw-r--r--  1 root 425K 2022-04-25 17:31 modules.symbols.bin

对于一个已经运行了2年并进行了所有内核升级的系统来说,这大约是50个旧目录。对于普通的Intel/AMD系统来说,大约是100兆字节,而对于树莓派来说,总共超过300兆字节 - 随着时间的推移,这些数量会增加。
所以我想知道为什么这些已删除内核的旧模块目录和文件不作为清理过程的一部分被删除呢?
最近我从Ubuntu 20.04升级到了22.04(这就是为什么我正在做一些清理工作的原因)。
鉴于目前的情况,我在想是否应该为这些剩余的目录编写自己的清理脚本。不过,我还是很好奇为什么这不是自动完成的。

1我不能回答为什么它们被保留,因为我自己也不确定,所以我会将这个作为评论。如果你想清理它们,你可以使用以下命令(它使用了干运行选项,所以如果你对它将删除的结果满意,你需要移除该选项)apt purge $(dpkg -l | grep "^rc\s*linux" | awk '{print $2}') --dry-run - Dan
3这被称为谨慎。最好不要自动删除某些东西,而是删除可能破坏系统的东西。你系统上那几个KB并没有造成任何损害。请注意,由于我们现在会自动删除旧内核...我们可以将此视为一个错误 :) - Rinzwind
1这里有一个非常好用的旧内核清理管理工具:https://code.launchpad.net/linux-purge。 - Doug Smythies
1FYI:请检查一下您是否将它们标记为手动安装;即通过apt install修复了问题...导致通常会自动安装的内核被标记为手动安装,因此无法通过您的工具关闭自动程序进行清理。 - guiverc
3个回答

我不知道为什么

我觉得你不会得到一个关于Ubuntu为什么以某种方式做某事的好答案。

历史

直到几年前,Ubuntu根本不清理任何内核和内核头文件包。现在软件更新会删除旧的和未使用的内核。我认为它运行的类似于:

sudo apt autoremove

不幸的是,它会留下那些模块文件。

向前迈进

您不必编写脚本来摆脱它们。以下命令将完成任务:

sudo apt --purge autoremove

注意,在软件更新进行清理之前,您必须运行此命令。

清理

至于剩下的现有模块,您将需要手动删除它们,确保不要删除当前正在使用的任何模块文件夹。

使用此命令查找已安装内核的列表:

apt list --installed linux-image*

如果Ubuntu已经删除了旧的内核,那么你应该会看到两个或三个条目,其中包括linux-image元包linux-image-generic。记下安装内核的版本号,并确保不要删除已安装内核的/lib/modules/子文件夹。 希望这能帮到你。

1uname -r会告诉你当前正在使用的内核版本;任何不同编号的内核都可以被删除。dpkg --list | grep linux-image- | grep -v "$(uname -r)"会列出可能需要删除的内核,但会排除当前正在使用的内核。请注意,如果只有一个hwe条目,请考虑保留它,或者如果有多个匹配你的内核,请选择其中一个。 - Hannu

背景信息

根据评论和@user68186的回答,我现在可以得出结论,为什么隐含地遵循了apt在底层的工作方式。

我问题中的模块文件显然属于配置文件类别,这意味着它们不会在正常的apt autoremove命令中被删除,只有在提供--purge选项时才会被删除。

然而,特别是对于树莓派(以及可能的其他特殊架构),如果系统长时间运行并进行内核更新,这些配置文件可能会达到几个千兆字节。

因此,了解sudo apt autoremove --purge选项是很重要的,它会删除所有先前的内核配置文件,包括模块配置。

自动化内核管理工具

正如@DougSmythies所指出的,有一个名为linux-purge的自动化内核管理工具。我已经测试过它,似乎工作得很好。

要安装此实用程序,请执行以下操作(作为root用户)。这将安装脚本、man页和bash自动补全。

$ wget https://git.launchpad.net/linux-purge/plain/update-linux-purge
$ chmod +x ./update-linux-purge && ./update-linux-purge

现在,你可以使用命令linux-purge来使用这个实用工具,并且它的手册页面可以通过man linux-purge来查看。
例如,要清除所有旧的内核(不包括/boot中存在的内核),运行以下命令:
linux-purge -b

进行中的错误报告

此外,由于该问题已在Ubuntu讨论区报告,错误报告已被开启以解决此问题。有兴趣的人可以在那里跟踪进展。


1运行'update-linux-purge'命令无法生效,因为该文件不在路径中,需要加上前缀'./'。 - trash80

对于像我这样的懒骨头,我创建了这个文件。
cat /etc/apt/apt.conf.d/zz_purge 
APT::Get::Purge "true";
Binary::apt::Purge "true";

APT::Get::AutomaticRemove "true";
APT::Get::Purge-Unused "true";
Binary::apt::APT::Purge-Unused "true";
Binary::apt::APT::AutomaticRemove "true";

无论我使用apt还是apt-get,并使用autoremove,我的软件包都会被清除。而且每当我安装或删除一个软件包时,不再需要的软件包也会被清除。

我也一样,我会在你的列表中加上 'APT::Install-Recommends "false";' :) - Arul Selvan