2

I'm running a bit low on disk space and noticed that I have several kernels that I'm probably never going to use taking up space. There was a program called computer janitor that cleaned things up (and a lot of things that you didn't want cleaned up), but I can't find it. Is there a preferred alternative?

Many thanks!

3 Answers3

1
  1. First, you need to see which kernel you currently use, because you must not delete it. Yoy can see that using the command:

    uname -r

  2. Then, you can see the installed kernels using the command:

    dpkg --list | grep linux-image

  3. And you can delete an extra kernel, using apt-get like this:

    sudo apt-get purge linux-image-x.x.x-x-generic

Where x.x.x-x is the kernel you want to remove. Remember, you must not delete the one that is currently in use (the output from uname -r). You should keep a second kernel as a back up, in case the first somehow fails.

An alternative, would be the Janitor of Ubuntu Tweak, which has the option of removing unused kernels.

Elias Ps
  • 656
1

I wrote a Bash function for this very purpose. Sharing is caring, so here we go with a Bash function I have been using successfully on Debian 5 and 6 as well as Ubuntu versions between 10.04 and 12.10. It has evolved a bit over time but never failed me. It automates the "decision process".

NB: feel free to point out flaws and suggest improvements and I'll try my best to incorporate them.

function prune-kernels
{
        [[ -f "/etc/debian_version" ]] || { echo -e "\033[01;32mERROR:\033[00m This has only been tested on Debian/Ubuntu."; return; }
        [[ -e "/vmlinuz" ]] || { echo -e "\033[01;32mERROR:\033[00m Expected /vmlinuz to exist."; return; }
        [[ "$UID" -eq "0" ]] || local SUDO=sudo
        # Figure out the name of the newest and the previous kernel
        local OLDKRNL=$(readlink -f /vmlinuz.old)
        local NOWKRNL=$(readlink -f /vmlinuz)
        # If vmlinuz doesn't exist, Also prune "/vmlinuz.old"?
        [[ -e "/vmlinuz.old" ]] || OLDKRNL="$NOWKRNL"
        # Also prune "/vmlinuz.old"? If so, pretend old and new have the same name to skip only the new one
        [[ "$1" == "--old" ]] && local OLDKRNL="$NOWKRNL"
        # Strip path
        OLDKRNL="${OLDKRNL##*/vmlinuz-}"
        NOWKRNL="${NOWKRNL##*/vmlinuz-}"
        local VERSIONS=$(echo $(for krnl in /boot/vmlinuz-*; do echo "${krnl##*/vmlinuz-}"; done) $(for krnl in $(dpkg -l|command grep 'linux-image'|command grep '^ii'|command grep -v 'meta-package'|command grep 'linux-image-[[:digit:]]\.[[:digit:]]*\.[[:digit:]]'|awk '{print $2}'); do echo ${krnl##linux-image-}; done)|sort|uniq|sed -e "s:$NOWKRNL::g;s:$OLDKRNL::g;s:$(uname -r)::g")
        echo -ne "\033[01;32mSkipping \033[01;33mthe following kernels:\033[00m $NOWKRNL"
        [[ "$(uname -r)" == "$NOWKRNL" ]] || { echo -ne ", $(uname -r)"; }
        echo -ne " (\033[0;32mcurrently running\033[00m)"
        [[ "$OLDKRNL" == "$NOWKRNL" ]] || echo -ne ", $OLDKRNL (\033[0;33mold kernel\033[00m)"
        echo ""
        # Remove packages
        local PACKAGES=$(for i in $VERSIONS; do echo -n "linux-image-$i linux-headers-$i "; done)
        if [[ -n "$PACKAGES" ]]; then
                echo -e "\033[0;32m[STEP 1] \033[01;33mRemoving packages\033[00m"
                $SUDO apt-get remove $PACKAGES || { echo -e "\033[01;31mSeems that apt-get was not successful, aborting.\033[00m"; return; }
        else
                echo -e "\033[01;32mNo packages need to be removed.\033[00m"
        fi
        # Remove any remaining kernel images etc from /boot
        local FILES=$(for fname in $(for i in $VERSIONS; do echo -n "/boot/abi-$i /boot/initrd.img-$i config-$i System.map-$i vmcoreinfo-$i vmlinuz-$i "; done); do [[ -f "$fname" ]] && { echo -n "$fname "; }; done)
        if [[ -n "$FILES" ]]; then
                echo -e "\033[0;32m[STEP 2] \033[01;33mNow removing remaining files:\033[00m $FILES"
                $SUDO rm -f $FILES
        else
                echo -e "\033[01;32mNothing else to clean up.\033[00m"
        fi
}

Put the function into a file and source it from your .bashrc or simply source it from the shell ad hoc and run it then. Unless you did something fancy to your apt-get settings, this will prompt before taking action.

The function also takes a parameter --old to remove all but the running kernel. By default it will skip the running and the old (/vmlinuz.old) kernels during pruning.

Also note: this function does work nicely even in scenarios where the running kernel is older than the current (/vmlinuz link) and the old (/vmlinuz.old link) kernels.

Disclosure: almost 1:1 copy from an earlier answer by me here.

0xC0000022L
  • 5,720
1

I have an old answer on this topic that is very helpful: How to find old kernels

It purposefully stops short of removing the packages because that's a lot of responsibility on my shoulders. The script will remove new kernels if you haven't rebooted since installing them. It won't hold your hand.

I've written a quick variant on the command that shows everything but the current kernel. You could use this as a basis for removing but whatever you do with it, you need to check that you're not removing kernels you just installed.

dpkg -l | grep -Eo "^.i +linux-(image|headers)[^ ]+" | cut -c 5- | grep -v `uname -r`
Oli
  • 293,335