强制删除不需要的linux-image-extra*软件包

长话短说,我卡在一堆不需要的、半配置的图像包上,正试图摆脱它们。
$ dpkg -l |grep linux-im
iF  linux-image-3.13.0-100-generic       3.13.0-100.147 i386 Linux kernel image for version 3.13.0 on 32 bit x86 SMP
iF  linux-image-3.13.0-101-generic       3.13.0-101.148 i386 Linux kernel image for version 3.13.0 on 32 bit x86 SMP
iF  linux-image-3.13.0-92-generic        3.13.0-92.139  i386 Linux kernel image for version 3.13.0 on 32 bit x86 SMP
iF  linux-image-3.13.0-93-generic        3.13.0-93.140  i386 Linux kernel image for version 3.13.0 on 32 bit x86 SMP
iF  linux-image-3.13.0-96-generic        3.13.0-96.143  i386 Linux kernel image for version 3.13.0 on 32 bit x86 SMP
iH  linux-image-extra-3.13.0-100-generic 3.13.0-100.147 i386 Linux kernel extra modules for version 3.13.0 on 32 bit x86 SMP
iH  linux-image-extra-3.13.0-101-generic 3.13.0-101.148 i386 Linux kernel extra modules for version 3.13.0 on 32 bit x86 SMP
iH  linux-image-extra-3.13.0-92-generic  3.13.0-92.139  i386 Linux kernel extra modules for version 3.13.0 on 32 bit x86 SMP
iH  linux-image-extra-3.13.0-93-generic  3.13.0-93.140  i386 Linux kernel extra modules for version 3.13.0 on 32 bit x86 SMP
iH  linux-image-extra-3.13.0-96-generic  3.13.0-96.143  i386 Linux kernel extra modules for version 3.13.0 on 32 bit x86 SMP

这些图片其实是无用的,因为我的32位14.04系统是运行在一个OpenVZ容器中的,这个容器完全负责内核。正如你所看到的,它是一个更早的版本。
$ uname -r
2.6.32-042stab116.2

因此,与大多数类似的问题不同,这里我试图做的是完全清除所有这些3.13版本的软件包,这些软件包本来就不应该存在。
这是我迄今为止的尝试总结。
尝试使用常规方法(apt-get、apt、aptitude,无论哪种方式)来移除/清除软件包似乎不起作用,因为存在明显的恶性循环。
sudo apt-get purge linux-image-3.13.0-100-generic linux-image-3.13.0-101-generic linux-image-3.13.0-92-generic linux-image-3.13.0-93-generic linux-image-3.13.0-96-generic linux-image-extra-3.13.0-100-generic linux-image-extra-3.13.0-101-generic linux-image-extra-3.13.0-92-generic linux-image-extra-3.13.0-93-generic linux-image-extra-3.13.0-96-generic

output中可以看出,实际上没有任何东西被移除。另一方面,aptitude则能够进一步一些。
sudo aptitude purge linux-image-3.13.0-100-generic linux-image-3.13.0-101-generic linux-image-3.13.0-92-generic linux-image-3.13.0-93-generic linux-image-3.13.0-96-generic linux-image-extra-3.13.0-100-generic linux-image-extra-3.13.0-101-generic linux-image-extra-3.13.0-92-generic linux-image-extra-3.13.0-93-generic linux-image-extra-3.13.0-96-generic

此过程结束时,*image-3.13*已经消失,与之匹配的文件和文件夹通常位于/boot/lib/modules中,但是image-extra仍然报告为半安装状态(尽管经过dpkg -L验证似乎不包含任何文件...)。
此外,依赖关系现在已经破坏,因为在这个阶段重复清除会导致apt抱怨/boot/lib/modules中缺少文件/文件夹。我尝试在预期位置放置虚拟文件,如此处建议的那样,但最终还是遇到了原始错误。以下是我认为关键的摘录部分:
[...]
Removing linux-image-extra-3.13.0-101-generic (3.13.0-101.148) ...
run-parts: executing /etc/kernel/postinst.d/apt-auto-removal 3.13.0-101-generic /boot/vmlinuz-3.13.0-101-generic
run-parts: executing /etc/kernel/postinst.d/initramfs-tools 3.13.0-101-generic /boot/vmlinuz-3.13.0-101-generic
update-initramfs: Generating /boot/initrd.img-3.13.0-101-generic
E: /usr/share/initramfs-tools/hooks/fixrtc failed with return 1.
update-initramfs: failed for /boot/initrd.img-3.13.0-101-generic with 1.
run-parts: /etc/kernel/postinst.d/initramfs-tools exited with return code 1
dpkg: error processing package linux-image-extra-3.13.0-101-generic (--purge):
subprocess installed post-removal script returned error exit status 1
[...]

尝试了一下,不成功的话,一个所谓的核选项:
sudo dpkg --remove --force-remove-reinstreq package_name

我没有想法了。

我有点深入研究了一下,我有一种直觉,错误源自dpgk/etc/kernel/postrm.d中运行脚本的地方。 - yeedle
3个回答

鉴于以下情况:

  • linux-image-3.13.0-XXX-generic 已成功清除
  • linux-image-extra-3.13.0-XXX-generic 仍被报告为半安装状态
  • 当前没有任何已安装的软件依赖于这些 image-extra
  • 这些镜像本应不存在(因为2.6内核由宿主机OpenVZ容器提供)
  • 传统尝试均未能成功清理系统

那么一种可能的方法是从 dpkg 数据库中强制清除这些悬挂条目,如此处所建议

请注意:这是一种破解式、低层级的、潜在危险的操作。

  • 寻找属于要删除的软件包的任何文件(尝试使用$ dpkg -L linux-image-extra-3.13.0-XXX-generic命令),并将其删除。
  • 打开文件/var/lib/dpkg/status,定位并删除描述你希望dpkg忘记的软件包的文本块。
  • 在维护软件包描述符之间的空行、行首的空格等方面要特别小心。据说apt数据库对拼写错误是毫不留情的。
  • 保存status文件后,dpkg以及所有与apt相关的程序应该恢复正常。

我在一个bash脚本中使用以下命令来清除除了活动内核以外的一切:

dpkg -l linux-* | awk '/^ii/{ print $2}' | grep -v -e "$(uname -r | cut -f1,2 -d"-")" | grep -e "[0-9]" | grep -E "(image|headers)" | xargs sudo apt-get -y purge

这与你所调用的相当接近,但可能是dpkg是必要的区别。
如果感兴趣,完整的脚本集在这里:
https://github.com/mtompkins/linux-kernel-utilities

据我所知,这行代码只是对所有适用的软件包调用apt-get purge命令。我已经多次尝试了,但都没有成功。 - Giuseppe
这确实是它所能做的全部,但我不确定你是否以某种方式正确传递了软件包名称,并且希望dpkg命令可以处理它。不用担心。 - Mark

执行`ls /boot`命令应该显示一些`vmlinuz-X.XX.XX`文件。对于每个文件,执行`apt-get purge linux-image-X.XX.XX-generic`命令,但不要删除正在运行的内核。可以使用`uname -r`命令来检查当前正在运行的内核版本。

@Zanna 修正问题。 - user595510
酷,我建议再留一个备用核心。 - Zanna
2@MarkYisri,/boot文件夹根本没有任何条目。正如我所写的,Ubuntu是在一个OpenVZ容器内运行的,而内核(参见问题)属于主机,我对此无法控制。另外,无法成功使用apt-get purge来清除这些无关的软件包是问题的核心所在。 - Giuseppe