When you list your LINUX kernels you will find out that upgrading to a new version does not remove the old kernel.
It stays on disk and inside the grub
boot-manager menu as a fallback-system.
This may become a problem when your /boot
file-system is of restricted size
(maybe due to a dedicated boot-partition).
Anyway these kernels are not needed in case your LINUX starts up nicely after upgrade.
This Blog is about how to remove unused kernels.
Mind that the preceding '$' in all commands below is the UNIX terminal prompt and does not belong to the command itself.
Listing Kernels
I did this on
Ubuntu, which is a
Debian system, thus I used
dpkg
to list kernels.
$ dpkg --list | grep "linux-" | grep "image-" rc linux-image-3.13.0-32-generic 3.13.0-32.57 amd64 Linux kernel image for version 3.13.0 on 64 bit x86 SMP rc linux-image-3.13.0-43-generic 3.13.0-43.72 amd64 Linux kernel image for version 3.13.0 on 64 bit x86 SMP rc linux-image-3.13.0-44-generic 3.13.0-44.73 amd64 Linux kernel image for version 3.13.0 on 64 bit x86 SMP rc linux-image-3.13.0-45-generic 3.13.0-45.74 amd64 Linux kernel image for version 3.13.0 on 64 bit x86 SMP rc linux-image-3.13.0-46-generic 3.13.0-46.79 amd64 Linux kernel image for version 3.13.0 on 64 bit x86 SMP rc linux-image-3.13.0-53-generic 3.13.0-53.89 amd64 Linux kernel image for version 3.13.0 on 64 bit x86 SMP rc linux-image-3.13.0-74-generic 3.13.0-74.118 amd64 Linux kernel image for version 3.13.0 on 64 bit x86 SMP ii linux-image-3.13.0-92-generic 3.13.0-92.139 amd64 Linux kernel image for version 3.13.0 on 64 bit x86 SMP rc linux-image-4.15.0-42-generic 4.15.0-42.45 amd64 Signed kernel image generic ii linux-image-4.15.0-43-generic 4.15.0-43.46 amd64 Signed kernel image generic ii linux-image-4.15.0-48-generic 4.15.0-48.51 amd64 Signed kernel image generic rc linux-image-4.4.0-124-generic 4.4.0-124.148 amd64 Linux kernel image for version 4.4.0 on 64 bit x86 SMP rc linux-image-4.4.0-128-generic 4.4.0-128.154 amd64 Linux kernel image for version 4.4.0 on 64 bit x86 SMP rc linux-image-4.4.0-131-generic 4.4.0-131.157 amd64 Linux kernel image for version 4.4.0 on 64 bit x86 SMP rc linux-image-4.4.0-138-generic 4.4.0-138.164 amd64 Linux kernel image for version 4.4.0 on 64 bit x86 SMP rc linux-image-4.4.0-140-generic 4.4.0-140.166 amd64 Linux kernel image for version 4.4.0 on 64 bit x86 SMP rc linux-image-4.4.0-31-generic 4.4.0-31.50 amd64 Linux kernel image for version 4.4.0 on 64 bit x86 SMP rc linux-image-4.4.0-34-generic 4.4.0-34.53 amd64 Linux kernel image for version 4.4.0 on 64 bit x86 SMP rc linux-image-4.4.0-83-generic 4.4.0-83.106 amd64 Linux kernel image for version 4.4.0 on 64 bit x86 SMP rc linux-image-4.4.0-87-generic 4.4.0-87.110 amd64 Linux kernel image for version 4.4.0 on 64 bit x86 SMP rc linux-image-4.4.0-92-generic 4.4.0-92.115 amd64 Linux kernel image for version 4.4.0 on 64 bit x86 SMP rc linux-image-4.4.0-97-generic 4.4.0-97.120 amd64 Linux kernel image for version 4.4.0 on 64 bit x86 SMP rc linux-image-4.4.0-98-generic 4.4.0-98.121 amd64 Linux kernel image for version 4.4.0 on 64 bit x86 SMP rc linux-image-extra-3.13.0-32-generic 3.13.0-32.57 amd64 Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP rc linux-image-extra-3.13.0-43-generic 3.13.0-43.72 amd64 Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP rc linux-image-extra-3.13.0-44-generic 3.13.0-44.73 amd64 Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP rc linux-image-extra-3.13.0-45-generic 3.13.0-45.74 amd64 Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP rc linux-image-extra-3.13.0-46-generic 3.13.0-46.79 amd64 Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP rc linux-image-extra-3.13.0-53-generic 3.13.0-53.89 amd64 Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP rc linux-image-extra-3.13.0-74-generic 3.13.0-74.118 amd64 Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP ii linux-image-extra-3.13.0-92-generic 3.13.0-92.139 amd64 Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP rc linux-image-extra-4.4.0-124-generic 4.4.0-124.148 amd64 Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP rc linux-image-extra-4.4.0-128-generic 4.4.0-128.154 amd64 Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP rc linux-image-extra-4.4.0-131-generic 4.4.0-131.157 amd64 Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP rc linux-image-extra-4.4.0-138-generic 4.4.0-138.164 amd64 Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP rc linux-image-extra-4.4.0-140-generic 4.4.0-140.166 amd64 Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP rc linux-image-extra-4.4.0-31-generic 4.4.0-31.50 amd64 Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP rc linux-image-extra-4.4.0-34-generic 4.4.0-34.53 amd64 Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP rc linux-image-extra-4.4.0-83-generic 4.4.0-83.106 amd64 Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP rc linux-image-extra-4.4.0-87-generic 4.4.0-87.110 amd64 Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP rc linux-image-extra-4.4.0-92-generic 4.4.0-92.115 amd64 Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP rc linux-image-extra-4.4.0-97-generic 4.4.0-97.120 amd64 Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP rc linux-image-extra-4.4.0-98-generic 4.4.0-98.121 amd64 Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP ii linux-image-generic 4.15.0.48.50 amd64 Generic Linux kernel image ii linux-signed-generic 4.15.0.48.50 amd64 Complete Signed Generic Linux kernel and headers (dummy transitional package) rc linux-signed-image-3.13.0-44-generic 3.13.0-44.73 amd64 Signed kernel image generic rc linux-signed-image-3.13.0-45-generic 3.13.0-45.74 amd64 Signed kernel image generic rc linux-signed-image-3.13.0-46-generic 3.13.0-46.79 amd64 Signed kernel image generic rc linux-signed-image-3.13.0-53-generic 3.13.0-53.89 amd64 Signed kernel image generic rc linux-signed-image-3.13.0-74-generic 3.13.0-74.118 amd64 Signed kernel image generic rc linux-signed-image-4.4.0-124-generic 4.4.0-124.148 amd64 Signed kernel image generic rc linux-signed-image-4.4.0-128-generic 4.4.0-128.154 amd64 Signed kernel image generic rc linux-signed-image-4.4.0-131-generic 4.4.0-131.157 amd64 Signed kernel image generic rc linux-signed-image-4.4.0-138-generic 4.4.0-138.164 amd64 Signed kernel image generic rc linux-signed-image-4.4.0-140-generic 4.4.0-140.166 amd64 Signed kernel image generic rc linux-signed-image-4.4.0-31-generic 4.4.0-31.50 amd64 Signed kernel image generic rc linux-signed-image-4.4.0-34-generic 4.4.0-34.53 amd64 Signed kernel image generic rc linux-signed-image-4.4.0-83-generic 4.4.0-83.106 amd64 Signed kernel image generic rc linux-signed-image-4.4.0-87-generic 4.4.0-87.110 amd64 Signed kernel image generic rc linux-signed-image-4.4.0-92-generic 4.4.0-92.115 amd64 Signed kernel image generic rc linux-signed-image-4.4.0-97-generic 4.4.0-97.120 amd64 Signed kernel image generic rc linux-signed-image-4.4.0-98-generic 4.4.0-98.121 amd64 Signed kernel image generic
When you find yourself with such a big list of kernels you don't want to remove them one by one. But before you apply a script you should try regular commands.
Regular Clean-Up Commands
First try this command:
$ sudo apt autoremove
Now check if they are gone. Listing /boot
shows existing kernel files:
$ ls -la /boot
Any file in that directory that is named vmlinuz
is a kernel. It should carry the version in its name.
It is accompanied by other files like initrd.img
,
so you should always remove a kernel by system-commands, not by a file-remove.
If old kernels are still present, try this command:
$ sudo apt-get autoremove --purge
Still not gone? Now you would need to remove them one by one, e.g. for linux-image-3.13.0-32-generic:
$ sudo apt-get -y --purge remove linux-image-3.13.0-32-generic
But in case you have as many old kernels as I had, you may appreciate following script.
Clean-Up by Script
Don't ever remove the current kernel! You can find out its version by this command:
$ uname -r 4.15.0-48-generic
Also don't remove linux-image-generic
.
To avoid any misconception, the following script just outputs command lines. Redirecting and executing the result is left up to you.
purge-generate.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | [ -z "$1" ] && { echo "SYNTAX: purge-generate.sh kernelversionhead" >&2 echo " Example: purge-generate.sh 4.4.0" >&2 exit 1 } KERNELVERSION=$1 list=`dpkg --list | grep linux- | grep image-` kernels=`echo "\$list" | awk ' /linux-image-'\$KERNELVERSION'/ || /linux-signed-image-'\$KERNELVERSION'/ || /linux-image-extra-'\$KERNELVERSION'/ { print $2 }'` [ -z "$kernels" ] && { echo "ERROR: no kernels found with version head $KERNELVERSION" >&2 echo "Found kernel images:" >&2 echo "$list" >&2 exit 2 } for kernel in $kernels do echo "sudo apt-get -y --purge remove $kernel" done |
Redirect the output of this script to another script, set the new script executable, and then check it for mistakes before executing it!
$ chmod 700 purge-generate.sh $ purge-generate.sh 3.13.0 >purge.sh # check purge.sh before executing it! $ chmod 700 purge.sh $ ./purge.sh
The script requires an argument which is the version-head for the kernel(s) to remove.
Mind that giving too few numbers (e.g. just "4.15"
) may include also the current kernel!
That's the reason why you need to look at the generated script before executing it.
If everything worked out fine and kernels have been removed,
you can update grub to remove obsolete menu items
(sometimes already done automatically by apt-get -y --purge
):
$ sudo update-grub
This will recreate /boot/grub/grub.cfg
which contains the menu items.
Further grub configurations you find in /etc/default/grub
(modify this before executing update-grub
!).
Script Comments
Lines 1-5:
The script first checks that the command line argument is not empty.
Mind that the argument may give just the start of the version,
so several kernels could be afftected!
In case no version match was given, the script outputs its syntax and exits.
Lines 7-13:
The commandline argument is taken into variable KERNELVERSION, which is later injected into
the awk
script below.
But first the kernels are found by listing all installed packages
and grep
-ing out those that are possibly kernel packages.
The `backticks` (command-substitution) put the output of the contained command into variable list
.
The awk
script reduces the list
to those lines that match the KERNELVERSION,
and outputs the name of the kernel image, which is the second word, addressed through $2
(which is not variable of the enclosing shell!).
Now the variable kernels
holds all kernels to remove.
Mind that the double quotes in echo "\$list"
are not dispensable.
Without them the shell would remove newlines from variable list
, and awk would receive just one single line.
Mind also the way how KERNELVERSION is injected into the awk
script.
The script-text for awk is enclosed into 'single quotes', which end directly before \$KERNELVERSION
,
and start again directly after.
The backslash before $KERNELVERSION
is needed due to the enclosing `backticks`, although
some shells allow to leave this out.
Lines 15-20:
In case no kernel matched the given version, the script exits and lists existing kernels.
Lines 22-25:
When kernels matched the given version, a command line to remove it gets generated for each of them.