On my Ubuntu 20.04LTS servers I have a cron job for deleting old kernel versions to prevent their /boot partitions from running out of space. It works by querying with dpkg-query
for the list of installed linux-image
packages and then feeding all but the last three of those to apt-get purge -y
. This works well most of the time.
Every once in a while, for various reasons, this process will select the currently running kernel for removal.
This shouldn't be a problem, since according to its manpage, apt-get
with
the -y
option should just abort in that case.
In reality however this causes the cron job to hang indefinitely.
The standard output from the job, which is captured in a file, shows:
Removing linux-image-5.4.0-100-generic (5.4.0-100.113) ...
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
Removing linux-image-5.4.0-100-generic
--------------------------------------
You are running a kernel (version 5.4.0-100-generic) and attempting to remove
the same version.
This can make the system unbootable as it will remove
/boot/vmlinuz-5.4.0-100-generic and all modules under the directory
/lib/modules/5.4.0-100-generic. This can only be fixed with a copy of the kernel
image and the corresponding modules.
It is highly recommended to abort the kernel removal unless you are prepared to
fix the system after removal.
Abort kernel removal? [yes/no]
The process tree (snipped from ps -axf
) looks like this:
828 ? Ss 0:00 /usr/sbin/cron -f
92591 ? S 0:00 \_ /usr/sbin/CRON -f
92592 ? Ss 0:00 \_ /bin/sh -c /usr/local/sbin/remove_old_kernels.sh >> /var/log/remove_old_kernels.log 2>&1
92593 ? S 0:00 \_ /bin/bash /usr/local/sbin/remove_old_kernels.sh
92598 ? S 0:14 \_ apt-get purge -y linux-image-5.4.0-100-generic
92785 pts/0 Ss+ 0:00 \_ /usr/bin/dpkg --status-fd 26 --no-triggers --force-depends --abort-after=1 --remove linux-generic:amd64 linux-image-generic:amd64 linux-modules-extra-5.4.0-100-generic:amd64 linux-image-5.4.0-100-generic:amd64
92798 pts/0 S+ 0:00 \_ /bin/sh /var/lib/dpkg/info/linux-image-5.4.0-100-generic.prerm remove
92799 pts/0 S+ 0:00 \_ /usr/bin/perl -w /usr/share/debconf/frontend /usr/bin/linux-check-removal 5.4.0-100-generic
92809 pts/0 S+ 0:00 \_ /usr/bin/perl /usr/bin/linux-check-removal 5.4.0-100-generic
So apt-get
emitted a request for confirmation in spite of the -y
option.
Worse, it even noticed it didn't have a means for actually reaching anyone for an answer, but instead of wisely giving up it created a pseudoterminal out of thin air and now senselessly waits for an answer to appear there.
How can I avoid that behaviour and reliably prevent apt-get
from asking any questions when run without a terminal?