When one installs kernels they need to get upgraded every once in a while and while normal packages are removed once they are upgraded, kernels are not. You can install a newer kernel and the old will still be present. The reason for this simple, if the updated kernel is not working correctly you can use the previous kernel to boot your machine and continue working. However, when you have done this several times there will be a huge list of kernels and these need to be removed every once in a while. I made a script once that removes obsolete kernels, but it was specific to Ubuntu only and I needed something similar for Debian. So I completely rewrote the script and this is the end result.

Include this in your .bashrc (or create a script for it) and use the following functions to remove kernels which are no longer needed (other then ¬†your running kernel). It will also remove any kernel header packages. You will not delete meta-packages for kernels, eg linux-image-generic or linux-image-generic-pae unless the kernel you are running is not the most recent one. The script looks at the dependencies (including reversed) to avoid such deletions. I’ve tested it on Debian and Ubuntu. In case of bugs, let me know!

This script is now also featured on the Tutorial section on the Ubuntuforums, click.

_egrep-pattern ()
        [ -z "$1" ] && return
        local regexp=$1
        for i in $*
        echo ${regexp}

rmkernel () {
        local cur_kernel="$(uname -r)"
        local all_kernels="$(dpkg -l | grep -- linux- | egrep -- "-(image|headers|backports|modules)" \
        | grep "^ii" | awk '{print $2}')"
        local cur_kernel_pkgs="$(echo -e "$all_kernels" | grep "$cur_kernel$")"
        local cur_kernel_img=$(echo -e "$cur_kernel_pkgs" | grep image)
        local cur_kernel_hdr=$(echo -e "$cur_kernel_pkgs" | grep headers)
        if [ -z "$cur_kernel_img" ]
                echo "Unable to get the current kernel package. What are you doing?" >&2
                echo "Possibly running in a chroot, eitherway aborting!" >&2
                return 1
        local cur_kernel_img_rdepends="$(apt-cache rdepends $cur_kernel_img | tail -n +3)"
        local cur_kernel_hdr_rdepends
        local cur_kernel_hdr_depends
        if [ -n "$cur_kernel_hdr" ]
                cur_kernel_hdr_rdepends="$(apt-cache rdepends $cur_kernel_hdr | tail -n +3)" 
                cur_kernel_hdr_depends="$(apt-cache depends $cur_kernel_hdr | egrep 'linux-(image|headers)' | grep Depends | awk '{print $2}')" 
        local keep="$(_egrep-pattern $cur_kernel_pkgs $cur_kernel_img_rdepends $cur_kernel_hdr_rdepends $cur_kernel_hdr_depends)"
        if [ -z "$keep" ]
                echo "Unable to determine which kernels to keep!" >&2
                echo "This should not happen in normal circumstances" >&2
                return 1
        local remove="$(echo -e "$all_kernels" | egrep -v "^($keep)$")"
        local rm_modules="$(find /lib/modules -mindepth 1 -maxdepth 1 -type d ! -name ${cur_kernel} )"
        if [ -n "$remove" ] || [ -n "$rm_modules" ]
                echo "Going to remove the following kernel packages:" $remove
                echo "Going to remove the following kernel modules directories afterwards:" $rm_modules
                echo "Waiting 5 seconds for ctrl-c to abort mission"
                sleep 3
                echo -n ..2
                sleep 1
                echo -n ..1
                sleep 1
                echo "..Start removal"
                if [ -n "$remove" ]
                        sudo aptitude -y purge $remove
                [ -n "$rm_modules" ] && sudo rm -rf $rm_modules
        return 0