为什么apt-get autoremove不会删除我的旧内核?

我的引导分区在SSD上,所以没有足够的空间安装超过8个内核版本,最终会因为旧版本占满了引导分区而无法安装某些内核更新。有很多关于如何删除旧版本(甚至如何自动化该过程)的问题,但我的问题很简单:为什么apt-get autoremove不能自动检测并删除它们,我能否让它这样做?我的意思是,apt-get本来就是安装它们的,所以它知道它们的存在,那为什么选择保留所有旧版本呢?

3可能是重复的问题:为什么Ubuntu不会自动删除旧内核? - Martin Schröder
1在大多数情况下,Autoremove确实会删除旧内核。内核会积累,是因为系统默认不会自动运行autoremove。这是unattended-upgrades中的一个设置,可以进行更改。当先前排队的apt操作(如安装新内核)失败(由于空间不足)时,Autoremove无法删除旧内核。请参阅https://bugs.launchpad.net/bugs/1357093,了解一个将开始自动删除旧内核的unattended-upgrades补丁。 - user535733
3个回答

关于为什么要这样做,可以参考文件/etc/apt/apt.conf.d/01autoremove-kernels

enter image description here

正如你所看到的,apt被告知永远不要自动删除内核,这是由另一个(脚本)文件/etc/kernel/postinst.d/apt-auto-removal告知的。就是这样。

enter image description here

如果您手动安装了两个选择的内核,即第一个和当前的内核,那么apt-autoremove只会删除您没有手动安装的旧版本,因此您始终会有这两个选项以及最新版本。
更新:
在/etc/kernel/postinst.d/apt-auto-removal中有以下部分:
if [ "$latest_version" != "$installed_version" ] \
   || [ "$latest_version" != "$running_version" ] \
   || [ "$installed_version" != "$running_version" ]
then
        # We have at least two kernels that we have reason to think the
        # user wants, so don't save the second-newest version.
        previous_version=
fi

所以,如果你比较一下01autoremove-kernels文件和uname -r的输出,你会意识到当前正在运行的内核和它之前的最新内核都被保留,不会被该脚本删除。事实上,还有另一个文件/etc/apt/apt.conf.d/01autoremove,其中有以下几行内容:
    APT
    {
      NeverAutoRemove
      {
            "^firmware-linux.*";
            "^linux-firmware$";
      };
  VersionedKernelPackages
  {
        # linux kernels
        "linux-image";
        "linux-headers";
        "linux-image-extra";
        "linux-signed-image";
        # kfreebsd kernels
        "kfreebsd-image";
        "kfreebsd-headers";
        # hurd kernels
        "gnumach-image";
        # (out-of-tree) modules
        ".*-modules";
        ".*-kernel";
        "linux-backports-modules-.*";
        # tools
        "linux-tools";
  };

所以你可以将这些注释掉,这样就可以使用apt-autoremove自动删除内核,不过请记住 - 这是自担风险的操作。

2非常有趣!我的/etc/apt/apt.conf.d/01autoremove-kernels文件有很多行,但其中只有两个版本:3.13.0.{39,43}。然而,dpkg -l linux-*命令列出了四个版本,即3.13.0.{39,40,41,43},所以除了/etc/apt/apt.conf.d/01autoremove-kernels文件之外,还有其他原因保留了这些中间版本的,对吗? - BlueBomber
刚刚更新了答案,快来看看吧。 - Sergiy Kolodyazhnyy
1简而言之:01autoremove 是你想要的文件,01autoremove-kernels 可能只是一种保护措施,以防止 apt 删除当前安装的内核和最新的内核(以防最新的内核出现问题)。 - Sergiy Kolodyazhnyy
1除非我误读了01autoremove,它只是防止依赖包(如linux-image-extra)被自动删除。更改它不会影响是否自动删除linux-image-3.16.0-31-generic。其中的任何模式都不匹配我们想要自动删除的软件包名称。 - Peter Cordes
我在想,也许aptitude有自己的不删除内核的逻辑,因为我的自动生成的01autoremove-kernels只列出了当前和上一个(-33和-34),但是-31仍然没有被自动删除。 - Peter Cordes
哦,刚意识到,也许我在/etc/kernel/postinst.d/apt-auto-removal重写01autoremove-kernels时需要重新启动aptitude。这是在最新内核的postinst期间由当前运行的aptitude安装完成的。 - Peter Cordes
更新:aptitude有自己的不删除旧内核的逻辑,我不知道它在哪里配置。但是,apt-get autoremove被配置为只保留当前和上一个内核包,这个方法是有效的。 - Peter Cordes
我有同样的问题,但是是关于_linux-headers_。在**/etc/apt/apt.conf.d/01autoremove**中注释掉#"linux-headers";没有起作用。 有人有什么建议吗? 例如,apt-get autoremove在内核上可以工作,但是对于头文件来说却不行,原因不明... - direwolf
1@PeterCordes 不要删除或注释掉 /etc/apt/apt.conf.d/01autoremove 文件中的行。这样做并不能帮助你自动删除旧版本内核包,反而可能产生意想不到的影响。该文件并不能防止自动删除 linux-image-extra,但可以防止匹配 NeverAutoRemove 部分中正则表达式的软件包被自动删除。 - jarno
2@BlueBomber,apt-get autoremove不会删除在/etc/apt/apt.conf.d/01autoremove-kernels中未列出的内核的原因是这些内核被标记为手动安装;请参考我的回答 - jarno
/etc/apt/apt.conf.d/01autoremove并不真正删除任何东西。它只是将软件包标记为可自动删除。其他人(用户、无人值守升级、定时任务等)仍然需要触发并运行自动删除。 - user535733
我想知道/etc/kernel/postinst.d/脚本何时运行。我的情况是内核安装失败,因为没有足够的磁盘空间来构建ramdisk。我无法自动删除旧的内核(最后只能手动删除它们),可能是因为在安装失败后脚本没有运行。 - Brent Baccala

对我来说,安装最新的(X)ubuntu(15.10)有所帮助。在早期版本中,内核包可能被标记为手动安装,至少如果是通过软件更新器安装的话,那么sudo apt-get autoremove --purge无法删除它们。关于这个问题有一些错误报告:Bug #1175637Bug #1439769
在早期版本中,你可以尝试使用sudo apt-mark auto $(apt-mark showmanual | grep -E "^linux-([[:alpha:]]+-)+[[:digit:].]+-[^-]+(|-.+)$")命令将内核包标记为自动安装,并随后运行sudo apt-get autoremove --purge来查看是否有所不同。该命令应该不会删除在/etc/apt/apt.conf.d/01autoremove-kernels中显示的内核包,但最安全的做法是先用--dry-run选项运行apt-get autoremove命令。

或者,您可以使用linux-purge更加有选择地清除旧内核,即使它们是手动安装的。


哦,autoremove命令往往会删除太多的内核,请参见Bug #1440608 - jarno
2apt-mark对我来说起了作用,真希望我能点赞十次:P - Mike Gleason jr Couturier

首先尝试删除旧的内核包,但如果/boot/initrd.img文件仍然存在,可以尝试以下方法:
删除 /boot/initrd.img-4.8.0-39-generic
sudo update-initramfs -d -k 4.10.0-37-generic

一次只删除一个initrd.img文件。