Remove old kernels from Ubuntu Linux
Even if you run
apt-get autoremove
regularly, for some reason or another, old kernels will start to build up over time. To save space and to keep your machine clean, you may want to clean up occasionally.
The following steps could probably be automated, but since playing around with removing kernels may be dangerous, I prefer (for once) to do it manually.
Bring your system up-to-date
The first step is to make sure your system is up-to-date. For me, the sequence to do that (for which I do have a script, of course) is:
sudo apt-get update
sudo apt-get dist-upgrade -yuf
sudo apt-get autoremove -y
sudo apt-get autoclean
Reboot
You may be prompted to reboot after this. Do it even if you are not, as you may be going to remove the kernel you are currently running. This may leave your machine in an unbootable state temporarily. Better not risk that.
Look which kernel you are running
Run
uname -r
and take note of the result. This is the kernel version you are running now.
Look which kernel-related packages you have installed
Run
dpkg -l | egrep "^ii *linux-(headers|image|modules|tools)-[1-9]"
. The kernel you are currently running should be the one with the highest version number.
Use
apt-get
(or your favourite tool) to remove everything that does not belong to the current kernel (or maybe also the one before that – to keep one older kernel is probably more superstition and hand-waving than actually useful but I do it anyway). Try to remove the old image packages all in one command, that should save same time as the boot structure needs to be re-built only once.
Look for left-over module directories
Finally, take a look at the
/lib/modules
directory. There may be sub-directories in there that belong to old kernel versions, for example if you had used VirtualBox on your version with older kernels, and additional files were put into these folders, so they were not deleted when the corresponding modules packages were removed. You can throw away everything that corresponds to kernels you just removed.
Script
Here is a script that tried to automate the identification process. It does not directly remove anything; it only tells you what you should do. One reason is that it doesn't really sort the kernel versions correctly; if for example parts of the version number change from one digit to two or from two to three, it will give you a wrong result. If you are happy, you can run it and pipe it through
| fgrep sudo | sh
to actually make it do something.
This comes obviously with no warranty whatsoever. I have tried on a number of real and virtual systems, and it worked fine there, but your mileage may vary.
#! /bin/bash
#
running_kernel_version="$(uname -r | sed 's/-generic$//')"
kernel_packages="$(dpkg -l | egrep '^ii *linux-(headers|image|modules|tools)-[1-9]' | awk '{print $2}')"
kernel_versions="$(for i in $kernel_packages
do
if echo $i | fgrep -q "$running_kernel_version"
then
:
else
echo $i | sed -E 's/^linux-(headers|image|modules|tools)-([-.0-9]+)(-generic|)$/\2/'
fi
done | sort -ur)"
keep_kernel_versions="$running_kernel_version $(echo $kernel_versions | cut -d ' ' -f 1-2)"
echo Keep kernel versions: $keep_kernel_versions
remove_kernel_versions="$(echo $kernel_versions | egrep -v '('"$(echo $keep_kernel_versions | sed 's/ /|/')"')')"
echo Remove kernel versions: $remove_kernel_versions
if [ -z "$remove_kernel_versions"]
then
echo No packages to remove
else
remove_kernel_packages="$(dpkg -l | egrep '^ii *linux-(headers|image|modules|tools)-('"$(echo "$remove_kernel_versions" | sed 's/ /|/')"')' | awk '{print $2}')"
echo Remove kernel packages: $remove_kernel_packages
echo "sudo apt remove -y $(echo $remove_kernel_packages)"
fi
remove_modules_folders="$(ls -d /lib/modules/* | egrep -v '('"$(echo $keep_kernel_versions | sed 's/ /|/')"')')"
if [ -z "$remove_modules_folders" ]
then
echo No folders to remove
else
echo Remove modules folders: $remove_modules_folders
echo "sudo rm -rf $(echo $remove_modules_folders)"
fi