实际上,这个问题的答案比我预期的要烦人一些。是的,是的,这是危险的,而且维护者们为了这个原因特意让它变得非常困难。但是如果你试图自动化你的基础架构来做类似的事情,我相信你确实知道你在做什么。在我的情况下,是因为我正在尝试在另一个脚本中清除(当前运行的)内核,并验证是否确实有一个更新的内核可用。
通过检查
debconf-get-selections
的输出,确实有一个选项可以为您预先选择这个值:
$ sudo debconf-get-selections | grep -B1 linux-base
# Abort kernel removal?
linux-base linux-base/removing-running-kernel boolean true
如果你使用
debconf-set-selections
将其设置为"false",然而,什么都不会改变。你仍然会被提示。
这导致了一些深入研究是什么在调用这个。事实证明,在相对较新的(Buster)Debian版本和可能的Ubuntu版本上,有一个单独的Perl脚本叫做
linux-check-removal
,它的目的似乎是忽略、重置,然后提示这个警告。
http://manpages.ubuntu.com/manpages/cosmic/man1/linux-check-removal.1.html
这个脚本是从给定内核的
prerm
dpkg
脚本中调用的,例如。
$ cat /var/lib/dpkg/info/linux-image-4.19.0-13-amd64.prerm
#!/bin/sh -e
version=4.19.0-13-amd64
image_path=/boot/vmlinuz-$version
if [ "$1" != remove ]; then
exit 0
fi
linux-check-removal $version
if [ -d /etc/kernel/prerm.d ]; then
DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \
--arg=$image_path /etc/kernel/prerm.d
fi
exit 0
验证其运行情况:
$ sudo linux-check-removal $(uname -r)
# "Yes" selected
E: Aborting removal of the running kernel
$ echo $?
1
$ sudo linux-check-removal $(uname -r)
# "No" selected
W: Removing the running kernel
$ echo $?
0
所以,实际的解决方案是用返回0的方式覆盖这个命令。
然而,尽管该命令使用了相对调用,但在从dpkg调用时,此脚本中的$PATH不包括/usr/local目录。因此,像你期望的那样,在/usr/local/bin中简单地覆盖脚本是行不通的。为了证明这一点,我修改了prerm脚本以打印$PATH和which值,然后调用apt remove命令。
Removing linux-image-4.19.0-13-amd64 (4.19.160-2) ...
PATH: /usr/sbin:/usr/bin:/sbin:/bin
WHICH: /usr/bin/linux-check-removal
W: Removing the running kernel
因此,我们被迫暂时将真正的
/usr/bin/linux-check-removal
移出路径,并安装一个简单的占位脚本,它只返回0。我能想到的最简单的方法是:
$ sudo mv /usr/bin/linux-check-removal /usr/bin/linux-check-removal.orig
$ echo -e '#!/bin/sh\necho "Overriding default linux-check-removal script!"\nexit 0' | sudo tee /usr/bin/linux-check-removal
$ sudo chmod +x /usr/bin/linux-check-removal
你可以选择删除
echo
行,但我将其包含在演示中。
现在,您可以成功地无需交互地清除正在运行的内核版本。
$ sudo apt purge -y linux-image-4.19.0-13-amd64
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
linux-headers-4.19.0-12-amd64 linux-headers-4.19.0-12-common linux-image-4.19.0-12-amd64
Use 'sudo apt autoremove' to remove them.
The following packages will be REMOVED:
linux-image-4.19.0-13-amd64*
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
After this operation, 270 MB disk space will be freed.
(Reading database ... 104395 files and directories currently installed.)
Removing linux-image-4.19.0-13-amd64 (4.19.160-2) ...
Overriding default linux-check-removal script!
I: /vmlinuz.old is now a symlink to boot/vmlinuz-4.19.0-12-amd64
I: /initrd.img.old is now a symlink to boot/initrd.img-4.19.0-12-amd64
/etc/kernel/postrm.d/initramfs-tools:
update-initramfs: Deleting /boot/initrd.img-4.19.0-13-amd64
/etc/kernel/postrm.d/zz-update-grub:
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.19.0-14-amd64
Found initrd image: /boot/initrd.img-4.19.0-14-amd64
Found linux image: /boot/vmlinuz-4.19.0-12-amd64
Found initrd image: /boot/initrd.img-4.19.0-12-amd64
done
(Reading database ... 99993 files and directories currently installed.)
Purging configuration files for linux-image-4.19.0-13-amd64 (4.19.160-2) ...
然后恢复原始的
linux-check-removal
:
$ sudo mv /usr/bin/linux-check-removal.orig /usr/bin/linux-check-removal
sudo apt remove linux-image-$(uname -r)
),我确实看到了你提到的对话框。我用箭头键移动到“NO”,然后按回车键,内核包被卸载了。要再次安装它,我必须运行sudo apt install linux-image-$(uname -r) linux-modules-extra-$(uname -r)
,因为模块包已被移除,但没有自动引入。不过,我想知道为什么你想要卸载正在运行的内核呢? - Zanna