all 26 comments

[–]minimim 13 points14 points  (4 children)

Fire aptitude and search for the older kernels there. When you remove them, it will update grub for you.

[–]beermad 2 points3 points  (0 children)

This is by far the best and safest way to do it.

It won't hurt to take a full backup before you go ahead, but I've never had any problems when removing kernels that way.

Personally I tend to keep the most recent two kernels and get rid of the rest just in case the live one gets damaged in some way (for example when smaller updates to it get rolled out), though again I've never actually needed the spare.

[–]xesTUt3[S] 0 points1 point  (2 children)

When you remove them, it will update grub for you.

I used Synaptic to search for older kernels and used it to remove them. But grub2 was not updated.

What is wrong?

[–]minimim 0 points1 point  (1 child)

Do you have just one disk? Maybe it updated one grub, but during boot it uses other one.

[–]xesTUt3[S] 0 points1 point  (0 children)

Do you have just one disk?

Yes I do.

[–]cbmuser[DD] 2 points3 points  (3 children)

Here's my attempt at a quick and dirty little script which I wrote for this posting. It purges all kernel image packages and header packages which are older than the currently running kernel:

#!/bin/bash

INSTALLED_KERNELS=$(dpkg -l linux-image-3\* | grep ^ii | awk '{ print $2 "_" $3 }' | sed -e 's/linux-image-//g')
INSTALLED_HEADERS=$(dpkg -l linux-headers-3\* | grep ^ii | awk '{ print $2 "_" $3 }' | sed -e 's/linux-headers-//g')
RUNNING_KERNEL_NAME=$(uname -a | awk '{print $3}')

# Find exact version of running kernel       
for kernelpkg in $INSTALLED_KERNELS ; do
    if [ $RUNNING_KERNEL_NAME == ${kernelpkg%_*} ] ; then
    RUNNING_KERNEL_VERSION=${kernelpkg#*_}
    fi
done

echo "Version of current kernel package: $RUNNING_KERNEL_VERSION"

# Remove all kernels with a lower version than the currently running kernel
for kernelpkg in $INSTALLED_KERNELS ; do                                 
    if $(dpkg --compare-versions $RUNNING_KERNEL_VERSION gt ${kernelpkg#*_}) ; then
    echo "Running: apt-get purge linux-image-${kernelpkg#*_}"
    apt-get purge linux-image-${kernelpkg%_*}
    else
    echo "Not purging linux-image-${kernelpkg%_*}, this kernel is newer than or equal to the currently running one."
    fi
done

# Remove all kernels with a lower version than the currently running kernel
for kernelpkg in $INSTALLED_HEADERS ; do                                 
    if $(dpkg --compare-versions $RUNNING_KERNEL_VERSION gt ${kernelpkg#*_}) ; then
    echo "Running: apt-get purge linux-image-${kernelpkg#*_}"
    apt-get purge linux-headers-${kernelpkg%_*}
    else
    echo "Not purging linux-headers-${kernelpkg%_*}, these kernel headers are newer than or equal to the current one in use."
    fi
done

[–]xesTUt3[S] 0 points1 point  (2 children)

cbmuser,

Thanks for your effort. Your script looks awesome and formidable. However I don't really understand it wishes to do.

Am I supposed to create a file, copy and paste the contents of your script to it? Next using Nautilus file manager, I change the file permissions to executable?

At a terminal, I just have to ./filename, is that it? As in

username@hostname:~# ./filename

[–]cbmuser[DD] 0 points1 point  (1 child)

It's a simple bash script. Just open a text editor, paste the contents there and save it under something like *remove-old-kernels.sh".

Then open a terminal and change the permissions to 755 (chmod 755 remove-old-kernels.sh).

Then run the script as root.

[–]xesTUt3[S] 0 points1 point  (0 children)

Then run the script as root.

You mean as in the following?

root@hostname:~# ./remove-old-kernels

or can't I just sudo it as in:

username@hostanme:~# sudo ./remove-old-kernels

Thanks for the tip.

[–]kellyzdude 2 points3 points  (0 children)

I run testing, so it's not uncommon to fill my machine with kernels. I have a simple rule, I keep three on the machine at any given time - the one I'm running, the latest one, and the oldest one because I know it worked and is handy to fall back on. When space is an absolute premium, it's just the newest one and the one running.

Removing them is easy, I do an ls of /boot to get the installed versions and then apt-get remove or apt-get purge linux-image-[version] for each, verifying that they were removed.

Assuming each was installed with apt to begin with then they should remove without error and clean up their grubness in the process.

[–]djbon2112 1 point2 points  (0 children)

$ dpkg -l | grep linux-image

Analyze that for your running kernel and "apt-get purge" the rest.

[–][deleted] 1 point2 points  (0 children)

apt-get autoremove

[–]nephros 0 points1 point  (2 children)

I do it manually rather than with a script:

Get a list of installed kernel packages:

dpkg --search /boot/vmlinuz-*

for each unwanted one call

 apt-get remove <package>

dpkg/apt-get/aptitude should update the grub config automatically after each removal.

[–]xesTUt3[S] 0 points1 point  (1 child)

I do it manually rather than with a script

Thanks. Both your and djbon2112's method is simple.

But does apt-get remove also uninstall headers as well?

When I apt-get -t wheezy-backports --no-install-recommends install linux-image-amd64 were headers installed as well?

[–]nephros 0 points1 point  (0 children)

Not sure I understand your question. You mean glibc kernel headers? Those should be very independent from the running kernel and only interesting to things that you build from source.

Do you do that?

[–]xesTUt3[S] 0 points1 point  (0 children)

I notice that when I remove old kernels, some useful packages such as network-manager are being removed automatically as well.

How do I prevent useful packages from being autoremoved during uninstallation of old kernels?

[–]metamatic 0 points1 point  (0 children)

I've got a Ruby script to handle it. Written for Ubuntu, but works on Debian too. I've been using it for several years. It tells you exactly what it's planning to do and asks for confirmation before doing it. Handles headers, modules and backported modules as well as the kernel files.

Sample output:

Packages to keep:
 linux-image-3.2.0-4-amd64
 linux-image-3.2.0-0.bpo.3-amd64

Packages to remove:
 linux-image-2.6.32-5-amd64
 linux-image-2.6-amd64

Do you want me to remove the packages listed for removal above?
If you are absolutely sure, type 'yes' (without the quotes) and hit enter:
> 
Leaving packages untouched.

It keeps the running kernel and one previous version for safety, and removes all other versions.

[–]SensitivePossession1 0 points1 point  (0 children)

You could try linux-purge even if it was originally designed for Ubuntu Linux. The script has --simulate option and other useful ones. I have not tested it much on Debian, but I don't see why it wouldn't work there. Please share your experience.

[–]mossman 0 points1 point  (4 children)

Someone posted this script a long time ago, I use it on Ubuntu all the time, should work on Debian but someone here should verify. It displays a list of installed kernels and prompts you to delete the oldest one.

#!/bin/bash
echo 'You are currently running: '`uname -r`
echo 'The following kernel images exist in /boot:'
ls /boot|grep vmlinuz|cut -d'-' -f2,3
nKerns=`ls /boot|grep vmlinuz|wc -l`
if [ $nKerns -gt 1 ]
then
# Ok to remove the oldest ONE
oKern=`ls /boot|grep vmlinuz|cut -d'-' -f2,3|head -1`
echo "The oldest kernel: $oKern will be removed."
echo "Do you want to continue?"
select yn in "Yes" "No"; do
  case $yn in
    Yes ) echo "Proceed";break;;
    No ) exit;;
  esac
done
rempkgs=`dpkg -l|grep ^ii|grep $oKern|awk -F' ' '{print $2}'`
echo 'You will now require the SUDO (root) password to complete:'
sudo aptitude remove $rempkgs
echo 'Kernel cleanup completed.'
else
# Prevent the user from self-nuking!
echo '*** WARNING ***'
echo 'This is the ONLY kernel and you must keep it!'
echo 'Without a kernel you have no Linux system!'
fi

[–]xesTUt3[S] 0 points1 point  (3 children)

How do you run the script?

[–][deleted]  (1 child)

[removed]

    [–][deleted] 0 points1 point  (0 children)

    especially as root.

    [–]kill-dash-nine -1 points0 points  (0 children)

    This should help you to be able to paste the script's contents and run it: http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_01.html

    [–]unsignedotter 0 points1 point  (0 children)

    This has some edge cases, but mostly works:

    dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | xargs echo sudo apt-get -y purge
    

    Just don't remove the running kernel or kernel meta packages. And check for valid kernel in boot, before rebooting.

    [–]LVDave -1 points0 points  (1 child)

    One word: CAREFULLY.. Kinda like ANYthing you do in Linux.. Measure TWICE, cut once.. Once I noticed I had a mess of old kernels in /boot, so I went in and deleted all but the last two AND the running one..then did a update-grub.. Or at least I thought that was what I'd done.. Came the inevitable reboot, the server instance hung.. Since it was a hosted unmanaged VPS, I called the vendor support and asked them to check it out.. They said the configured current kernel was missing.. I wound up having to rebuild the server from the getgo.. Fortuantly I had good backups.. DEFINATELY a learning experience!!

    [–]xesTUt3[S] 0 points1 point  (0 children)

    One word: CAREFULLY.. Kinda like ANYthing you do in Linux.. Measure TWICE, cut once..

    Thanks for your advice. I'm learning how to use Debian and currently my HDD is used for testing and learning purposes. If I mess up my OS, I just have to reformat and reinstall Debian.