Remove Old Kernels In Ubuntu With One Command

A while back I wrote a post on how to remove old kernels from your Ubuntu system. While that process works just fine, it is a four step process. One person who read that post left a comment with a nice command line one-liner that removes all but the currently running kernel. And while that one-liner works quite well, I must admit that I don’t understand all the regular expressions used in it, so I decided to try and come up with my own one-liner to remove the old kernels from my system.

I’m going to take you through this step by step so you can see how the individual commands in this one-liner tie together. If you’re impatient, you can skip to the end to see the final command.

Step 1) List all packages that start with “linux-“

We’ll use the dpkg command with the -l switch to list the packages, whether installed or not, that start with the string linux-.

[term]dpkg -l linux-*[/term]

Step 2) Filter that list to show only installed packages

To filter the list, I’m going to pipeline the output of the first command into the awk command. I’m also going to use awk to filter out everything but the package names.

[term]dpkg -l linux-* | awk ‘/^ii/{ print $2 }'[/term]

Step 3) Filter out packages for the currently running kernel

OK, so now I’m down to a pretty limited number of packages, but I don’t want to remove the packages for my currently running kernel. I’m going to use a few commands to do that. First off, I can determine my currently running kernel with the uname -r command. Currently on my system that command outputs: 2.6.32-25-generic.

To do my package filtering, I only want the numeric portion of that output. I’ll pipeline the output of uname -r and use the cut command with a hyphen as the field delimiter. I’ll cut fields 1 & 2.

[term]uname -r | cut -f1,2 -d”-“[/term]

Now I’m going to use this result as the filter for a grep command. In Linux, to use the result of one command as an argument in another command, you enclose the command in single back-quotes ( ` that’s the key to the left of the 1 on a standard US keyboard). So here’s my one-liner so far.

[term]dpkg -l linux-* | awk ‘/^ii/{ print $2}’ | grep -v -e `uname -r | cut -f1,2 -d”-“`[/term]

This is the output so far on my system:

[term]linux-firmware
linux-generic
linux-headers-2.6.32-24
linux-headers-2.6.32-24-generic
linux-headers-generic
linux-image-2.6.32-24-generic
linux-image-generic
linux-libc-dev
linux-sound-base[/term]

Step 4) Filter the list for only the kernel packages

So now I have a package list that excludes the packages for my current kernel. The only packages from the list above that I want to remove are: linux-headers-2.6.32-24, linux-headers-2.6.32-24-generic, linux-image-2.6.32-24-generic.

What makes these packages unique from the others in the list is that they all contain numbers. So I can use grep again to filter the list down to only packages with numbers in their names. I’ll pipeline the output of the previous command into grep -e [0-9].

[term]dpkg -l linux-* | awk ‘/^ii/{ print $2}’ | grep -v -e `uname -r | cut -f1,2 -d”-“` | grep -e [0-9][/term]

So now the output on my system is only the following:

[term]linux-headers-2.6.32-24
linux-headers-2.6.32-24-generic
linux-image-2.6.32-24-generic[/term]

Step 5) Make sure we don’t catch any stray packages

Some people have had problems with this one-liner catching the linux-libc-dev:amd64 package. Adding a

[term]grep -E “(image|headers)”[/term]

to the string fixes the problem. Now we have

[term]dpkg -l linux-* | awk ‘/^ii/{ print $2}’ | grep -v -e `uname -r | cut -f1,2 -d”-“` | grep -e [0-9] | grep -E “(image|headers)”[/term]

Step 6) Putting it all together: Removing the packages

So now that I have a good list of packages I can use another pipe and the xargs command to invoke apt-get to remove the packages. First I’m going to show it using the –dry-run switch with apt-get. That way you can give it a try without actually changing your system.

[term]dpkg -l linux-* | awk ‘/^ii/{ print $2}’ | grep -v -e `uname -r | cut -f1,2 -d”-“` | grep -e [0-9] | grep -E “(image|headers)” | xargs sudo apt-get –dry-run remove[/term]

If everything looks good after the dry run, you can go ahead and remove the old kernels with:

[term]dpkg -l linux-* | awk ‘/^ii/{ print $2}’ | grep -v -e `uname -r | cut -f1,2 -d”-“` | grep -e [0-9] | grep -E “(image|headers)” | xargs sudo apt-get -y purge[/term]

So there you have it. One command, albeit a long one, to remove the old kernels from your Ubuntu system. I imagine the same command should work on other Debian based systems as well, but I’ve only tested this on my 32 bit system. I’d be interested to know if it works just as well on a 64 bit system.

Update: It works just fine on 64 bit systems as well.

119 thoughts on “Remove Old Kernels In Ubuntu With One Command

    1. Linerd Post author

      I don’t think so. As far as I know “sudo apt autoremove” will only remove old dependencies that are no longer needed by your system. Say you wanted to install GIMP on your system and apt told you it had to install 10 dependencies so that GIMP would work. Those packages get flagged as required dependencies by apt and also get installed when you install GIMP. Now if you were to uninstall GIMP (sudo apt remove gimp) that would only remove GIMP itself. You could then use “sudo apt autoremove” to remove the no longer needed dependencies that had come in when you installed GIMP. Kernel packages are not brought in as dependencies so are not flagged by apt in the same way, so “sudo apt autoremove” is not going to remove old kernels for you.

      You don’t have to take my word for it though. Give it a try and see if it removes the older kernels from your system.

      https://askubuntu.com/questions/984797/clean-autoclean-and-autoremove-combining-them-is-a-good-step

      Edit: It looks like it may work, depending upon whether the kernels in question were automatically installed as unattended upgrades or not. Take a look at this link.
      https://help.ubuntu.com/community/RemoveOldKernels

      Reply
    2. Declan Pritchard

      I am using Ubuntu 22, (64 bit) and after wasted hours of following various tips (including autoremove) , “Remove Old Kernels In Ubuntu With One Command” worked wonderfully, and I liked the step by step build-up and explanation.

      Reply
  1. Samo

    Used this command after my boot was full on ubuntu 16.04 LTS server x64 and the server couldn’t boot any more. Restored from backup and used the apt autoremove –purge and after that i run update and upgrade and it worked.

    Reply
  2. Bobr

    Hi,
    Thanks so much for the best one-liner I ever heard !!
    Happened accross your pages 15th Oct 2016 from Ireland
    Just used it on my Zorin package and it still worked great after all this time.
    Its a pity you have not posted much recently as your solutions are so to the point, very engineer like “get it right first time”.

    Again thank you.
    Bob

    Reply
  3. Innocent Bystander

    NOT WORKING (LinuxMint Cinnamon 16.04 x64). The script removes the most recent kernel (4.4.0-28) while leaving the old one (4.4.0-21). Not sure what goes wrong, I would prefer to purge the old kernel instead.

    Reply
    1. Theo

      Try: sudo dpkg -l linux-* | awk ‘/^ii/{ print $2}’ | grep -v -e `uname -r | cut -f1,2 -d”-“` | grep -e [0-9] | grep -E “(image|headers)” | xargs sudo dpkg –remove

      Reply
  4. Georgi

    Thank you so much! I am using a 64bit Ubuntu Mate 16.04, and I wasn’t able to update my kernel. Your very good and detailed explanation helped me. Thank you!!!

    Reply
  5. Logisciel

    Good but, this remove META packages like : linux-image-amd64 linux-headers-amd64 on amd64 because 64 is grep

    Updated by:

    dpkg -l linux-* | awk ‘/^ii/{ print $2}’ | grep -v -e `uname -r | cut -f1,2 -d”-“` | grep -e [0-9]\.[0-9] | grep -E “(image|headers)”

    Reply
  6. Dasupergrover

    Bookmarked this site long ago, to use your awesomely constructed command to keep my ubuntu server ‘clean’

    Thanks!

    Reply
  7. Vauhti Vaino

    Scared like a little monkey – first dry run. Everything ok. Wet run, everything seems to be ok. Thanks, my friend! @vvaino

    Reply
    1. Mark

      I had an issue with my boot partition being 100% full on Ubuntu 14.04 and apt-get failing to work all together. So I ended up changing the final command to use dpkg to remove them…. So the final full command is …

      dpkg -l linux-* | awk ‘/^ii/{ print $2}’ | grep -v -e `uname -r | cut -f1,2 -d”-“` | grep -e [0-9] | grep -E “(image|headers)” | xargs sudo dpkg –remove

      Reply
  8. mrts

    I got really tired of all this unnecessary complexity and created a Python package that makes this trivial with a one-liner:

    [code]
    ubuntu-old-kernel-cleanup | xargs sudo apt-get -y purge
    [/code]

    Install it with

    [code]
    pip install git+http://github.com/mrts/ubuntu-old-kernel-cleanup.git
    [/code]

    See more at https://github.com/mrts/ubuntu-old-kernel-cleanup.

    Hope this helps others too.

    Reply
  9. gabo

    Thanks man, I have to sa y that I did it with fear, but at the end, it works, I was looking for it about few weeks without somethign that helps me, but this super large command works perfectly.

    Reply
  10. Flo

    great article! I’m here every month just to copy your command to remove old kernels on my ubuntu-NAS 🙂 thank you!

    Reply
  11. Citizen eight

    This article was one of the best! It has freed up my inodes usage (IUse%) from the high nineties to a more reasonable thirty percent (Ubuntu LTS 14.3 32bit)

    I’m somewhat puzzled that Ubuntu doesn’t offer this by itself or at least give some options to remove old(er) kernels when disk space/inode usage goes above a certain threshold.

    After this operation, 1725 MB disk space will be freed.
    (Reading database … 546864 files and directories currently installed.)

    A very big thanks to the author of this article! It was very helpful and thanks for publishing this.

    Reply
  12. LinuxUser

    Almost 10GB kernel files on my server… fuck. There’s no excuse Ubuntu doesn’t do some kind of automatic cleanup.

    Thanks for the script.

    Reply
    1. Marco

      Me too…. discovered using Fslint (what a great prog).

      I agree….. this should not be something you search for on the internet.
      Ubuntu should have this sorted by now.

      This page was reccomended from Ubuntu Forums……. what a great share that was.
      Great explanation, and of course a very well designed command.

      Thank you!

      Reply
  13. Christoph Koydl

    I was a little puzzled at first. It didn’t seem to work on zsh. After starting bash, everything was fine. Thanks.

    Reply
  14. Robintel

    Clears up the space on /boot and removes old kernel data from the system, as described.

    Works like a charm on Ubuntu 14 LTS x64 with crypto.

    Thank you very much for explaining what the command does and how it does it.

    This is invaluable info!

    Reply
  15. Rich

    Used the ‘very long command’

    “dpkg -l linux-* | awk ‘/^ii/{ print $2}’ | grep -v -e `uname -r | cut -f1,2 -d”-“` | grep -e [0-9] | xargs sudo apt-get -y purge”

    Worked like a charm. Plenty of space in /boot

    Reply
  16. Alessandro

    Hi to all!

    When i try the dry-run command I recive:
    The following packages have unmet dependencies:
    linux-image-generic-lts-quantal : Depends: linux-image-3.5.0-54-generic but it is not going to be installed
    E: Unmet dependencies. Try ‘apt-get -f install’ with no packages (or specify a solution).

    Mine kernel is 3.5.0-45, but I don’t know what is the package that depend from them…
    I can’t use apt-get -f install because my boot partition is full..
    Can anyone help me please ?
    Thank you very much, and apologize for my bad english!

    Reply
  17. kim jong oun

    this worked a treat. my /boot was full and giving issues on ubuntu 12.04.04 AMD 64bit. i was crapping myself trying to fix this, but the one liner worked!

    Reply
  18. john herring

    Thank you so much for this command. It worked perfectly! I had searched for hours to find a simple solution to the boot space problem.

    Reply
  19. CJ

    After confirming with “–dry-run remove” that only images and headers would be removed in my 12.04 64 bit system, I pulled the trigger.
    The last line of the result is “Do you want to continue [Y/n]? Abort.” and I’m returned to the prompt as if I’d aborted the command.
    Haven’t got a clue what went wrong.

    This command:
    dpkg -l linux-* | awk ‘/^ii/{ print $2}’ | grep -v -e `uname -r | cut -f1,2 -d”-“` | grep -e [0-9] | grep -E “(image|headers)” | xargs sudo apt-get remove

    Reply
    1. CR

      dpkg -l linux-* | awk ‘/^ii/{ print $2}’ | grep -v -e `uname -r | cut -f1,2 -d”-“` | grep -e [0-9] | grep -E “(image|headers)” | xargs sudo apt-get -y remove

      Will fix it. The xargs doesn’t like the prompting, so just skip it, since you’ve done the dry run already. You know what it’s going to do.

      Reply
    1. Linerd Post author

      Thanks for your comment.

      So, inserting a
      [term]grep -v libc[/term]
      will fix it in the case of libc-dev:amd64. Maybe I should make it so it only includes packages that start with “linux-image” or “linux-headers”, just in case some other problem package shows up. I can do that by adding
      [term]grep -E “(image|headers)”[/term]

      Reply
      1. P B

        Cheers for that. Maybe you could modify the date at the top of the page. It currently says October 2nd 2010 which gives a first impression that it’s 3 years old. And under the Updates include this latest tweak.
        Regards

        Reply
  20. P B

    It is only supposed to match kernel related packages but it is also finding packages like linux-libc-dev:amd64. As it begins with linux and has a number. People could get caught out with this and
    remove things they dont want removing.

    Reply
  21. Van Bastos

    I love you man. hahaha it really worked.

    Thanks for you very long command

    “dpkg -l linux-* | awk ‘/^ii/{ print $2}’ | grep -v -e `uname -r | cut -f1,2 -d”-“` | grep -e [0-9] | xargs sudo apt-get -y purge”

    Reply
  22. Skidder

    Thanks for this helpful command! However, I have one remark:

    I also have linux-libc-dev:amd64 installed, which became a candidate for removal because of the last check “only keep items with numbers in them”. Of course, including “grep -v libc” in the command solved this.

    Reply
    1. Some Dummy

      Or cut -f1,1 -d":". Also it may help to pray that the Linux people choose not to use numbers in any other necessary packages.

      Reply
  23. Vitalie Ciubotaru

    a nice command line one-liner that removes all but the currently running kernel
    While this is an accurate description, it might not be what we want. Imagine the following situation:
    1. I do `sudo apt-get update` and see that a new kernel is available.
    2. I install the new kernel. I don’t reboot (why would I, if everything works fine?)
    3. I realize that I have a bunch of older kernels in my system. I want to remove them.
    4. I run this one-liner. Instead of deleting everything except the newest kernel, it deletes everything except the currently running one. No gain.

    Reply
    1. Linerd Post author

      Why do you say no gain? You still got rid of all of those old kernels, didn’t you? And removing the running kernel certainly seems like a bad idea. In your scenario, the next time you install updates you should get the new kernel again. Now you only have one extra kernel rather than 5 or 10.

      Reply
  24. vacri

    Be careful, this will hit other packages as well – on my system (ubuntu 13.04) it also grabs “linux-libc-dev:amd64”.

    … which is pretty much what Rambo just said.

    Reply
  25. Rambo

    Hmm I think it willl work on a 64 system, im currently in the process of adjusting it a little though. The trick of picking out everything that contain numbers for processing doesnt work on 64 systems since we have filenames like *amd64 and so.

    Reply
  26. Pingback: /boot out of space

  27. Jeremy Acton

    Please could someone explain how to type the vertical line between phrases? I don’t see it on my keyboard ANYWHERE, and it’s obviously not the forward or back slashes.

    Reply
    1. Jeremy Acton

      don’t worry abt replying . sorted.
      Thanks for the excellent one liner. It works like a magic charm.

      Reply
  28. Pingback: » Time to Clean Up: Out of Space for New Kernels Linux Sagas

  29. John K

    Found this page when I needed to do some clean up on my system which was very helpful. I did make a change for filtering the package list that I would like to pass on:

    dpkg -l | awk –assign=mykernel=$(uname -r) ‘$2 ~ mykernel{next}$2 ~ /^linux-image-[0-9]/ || $2 ~ /^linux-headers-[0-9]/{print $2}’ | xargs sudo apt-get -y purge

    Reply
  30. Edgar Cheetham

    I have used your technique to remove old kernels and it has worked quite well in he past, and I thank you for that. However now, after upgrading from linux-headers-2.6.32-45 (2.6.32-45.103) to 2.6.32-45.104, when I type:
    :~$ dpkg -l linux-*
    I get this:
    No packages found matching linux-3.7.1.
    No packages found matching linux-3.8.0.
    What gives?

    Reply
      1. Edgar Cheetham

        I found the answer to my own question.
        It has nothing to do with the upgrade. It has something to do with me taking the crash course on how to build and run a Linux kernel. I built two kernels (3.7.1 and 3.8.0) but never run them. They are sitting in folders with said names in my Home Folder.
        I feel kinda dumb…
        Thanks

        Reply
        1. Jarno Suni

          Yes, and I suppose you ran the command in the home directory as well. However, if you quote the search pattern for dpkg, the packages are not expanded for the query: dpkg -l "linux -*".

          Reply
  31. Konstantin

    Did not work well on Ubuntu 12.10 (64bit) – it wanted to lot of extra things:

    Feb 22, 11:27:02> dpkg -l linux-* | awk ‘/^ii/{ print $2}’ | grep -v -e `uname -r | cut -f1,2 -d”-“` | grep -e [0-9] | xargs sudo apt-get –dry-run remove
    Reading package lists… Done
    Building dependency tree
    Reading state information… Done
    The following packages were automatically installed and are no longer required:
    lib32z1 libavahi-client-dev libavahi-common-dev libgnutls-openssl27 libgnutlsxx27 libgpg-error-dev libidn11-dev libieee1284-3-dev libjbig-dev libkadm5clnt-mit8 libkadm5srv-mit8 liblzma-dev libp11-kit-dev libsensors4-dev libsnmp-perl libtasn1-3-dev libtiffxx5
    libusb++-0.1-4c2 libv4l-dev libwrap0-dev ncurses-term pax
    Use ‘apt-get autoremove’ to remove them.
    The following packages will be REMOVED:
    build-essential comerr-dev g++ g++-4.4 g++-4.7 google-earth-stable krb5-multidev libc6-dev libcups2-dev libcupsimage2-dev libcurl4-nss-dev libexif-dev libexpat1-dev libgcrypt11-dev libgnutls-dev libgphoto2-2-dev libjpeg-dev libjpeg-turbo8-dev libjpeg8-dev
    libkrb5-dev libmysqlclient-dev libncurses5-dev libpcre3-dev libperl-dev libpng12-dev librtmp-dev libsane-dev libsnmp-dev libsqlite3-dev libssl-dev libstdc++6-4.4-dev libstdc++6-4.7-dev libtiff5-dev libtool libusb++-dev libusb-1.0-0-dev libusb-dev linux-generic
    linux-headers-3.5.0-23 linux-headers-3.5.0-23-generic linux-headers-3.5.0-25 linux-headers-3.5.0-25-generic linux-headers-generic linux-image-3.5.0-17-generic linux-image-3.5.0-18-generic linux-image-3.5.0-19-generic linux-image-3.5.0-21-generic
    linux-image-3.5.0-22-generic linux-image-3.5.0-23-generic linux-image-3.5.0-25-generic linux-image-extra-3.5.0-17-generic linux-image-extra-3.5.0-18-generic linux-image-extra-3.5.0-19-generic linux-image-extra-3.5.0-21-generic linux-image-extra-3.5.0-22-generic
    linux-image-extra-3.5.0-23-generic linux-image-extra-3.5.0-25-generic linux-image-generic linux-libc-dev lsb-core python-dev python2.7-dev ruby-dev ruby1.8-dev ruby1.9.1-dev zlib1g-dev
    0 upgraded, 0 newly installed, 66 to remove and 0 not upgraded.
    Remv build-essential [11.5ubuntu3]
    Remv libcurl4-nss-dev [7.27.0-1ubuntu1.1]
    Remv libcupsimage2-dev [1.6.1-0ubuntu11.3]
    Remv libcups2-dev [1.6.1-0ubuntu11.3]
    Remv libkrb5-dev [1.10.1+dfsg-2]
    Remv krb5-multidev [1.10.1+dfsg-2]
    Remv comerr-dev [2.1-1.42.5-1ubuntu2]
    Remv g++ [4:4.7.2-1ubuntu2]
    Remv libusb++-dev [2:0.1.12-23]
    Remv g++-4.4 [4.4.7-2ubuntu1] [libstdc++6-4.4-dev:amd64 ]
    Remv libstdc++6-4.4-dev [4.4.7-2ubuntu1]
    Remv g++-4.7 [4.7.2-2ubuntu1] [libstdc++6-4.7-dev:amd64 ]
    Remv libstdc++6-4.7-dev [4.7.2-2ubuntu1]
    Remv google-earth-stable [6.0.3.2197-r0]
    Remv ruby-dev [4.9]
    Remv ruby1.9.1-dev [1.9.3.194-1ubuntu1.3]
    Remv ruby1.8-dev [1.8.7.358-4ubuntu0.1]
    Remv lsb-core [4.0-0ubuntu26.1]
    Remv libsane-dev [1.0.23-0ubuntu1]
    Remv libtiff5-dev [4.0.2-1ubuntu2.1]
    Remv libsnmp-dev [5.4.3~dfsg-2.5ubuntu1]
    Remv libperl-dev [5.14.2-13ubuntu0.1]
    Remv librtmp-dev [2.4+20111222.git4e06e21-1]
    Remv libgnutls-dev [2.12.14-5ubuntu4.1]
    Remv python-dev [2.7.3-0ubuntu7]
    Remv python2.7-dev [2.7.3-5ubuntu4]
    Remv libssl-dev [1.0.1c-3ubuntu2.1]
    Remv libmysqlclient-dev [5.5.29-0ubuntu0.12.10.1]
    Remv libpng12-dev [1.2.49-1ubuntu1]
    Remv zlib1g-dev [1:1.2.7.dfsg-13]
    Remv libgphoto2-2-dev [2.4.14-2]
    Remv libusb-dev [2:0.1.12-23]
    Remv libusb-1.0-0-dev [2:1.0.12-2]
    Remv libtool [2.4.2-1ubuntu2]
    Remv libsqlite3-dev [3.7.13-1]
    Remv libpcre3-dev [1:8.30-5ubuntu1]
    Remv libgcrypt11-dev [1.5.0-3ubuntu1]
    Remv libexpat1-dev [2.1.0-1ubuntu1]
    Remv libexif-dev [0.6.20-3]
    Remv libncurses5-dev [5.9-10ubuntu1]
    Remv libjpeg-dev [8c-2ubuntu7]
    Remv libjpeg8-dev [8c-2ubuntu7]
    Remv libjpeg-turbo8-dev [1.2.1-0ubuntu2]
    Remv libc6-dev [2.15-0ubuntu20]
    Remv linux-generic [3.5.0.25.31]
    Remv linux-headers-3.5.0-23-generic [3.5.0-23.35]
    Remv linux-headers-3.5.0-23 [3.5.0-23.35]
    Remv linux-headers-generic [3.5.0.25.31]
    Remv linux-headers-3.5.0-25-generic [3.5.0-25.38]
    Remv linux-headers-3.5.0-25 [3.5.0-25.38]
    Remv linux-image-extra-3.5.0-17-generic [3.5.0-17.28]
    Remv linux-image-3.5.0-17-generic [3.5.0-17.28]
    Remv linux-image-extra-3.5.0-18-generic [3.5.0-18.29]
    Remv linux-image-3.5.0-18-generic [3.5.0-18.29]
    Remv linux-image-extra-3.5.0-19-generic [3.5.0-19.30]
    Remv linux-image-3.5.0-19-generic [3.5.0-19.30]
    Remv linux-image-extra-3.5.0-21-generic [3.5.0-21.32]
    Remv linux-image-3.5.0-21-generic [3.5.0-21.32]
    Remv linux-image-extra-3.5.0-22-generic [3.5.0-22.34]
    Remv linux-image-3.5.0-22-generic [3.5.0-22.34]
    Remv linux-image-extra-3.5.0-23-generic [3.5.0-23.35]
    Remv linux-image-3.5.0-23-generic [3.5.0-23.35]
    Remv linux-image-generic [3.5.0.25.31]
    Remv linux-image-extra-3.5.0-25-generic [3.5.0-25.38]
    Remv linux-image-3.5.0-25-generic [3.5.0-25.38]
    Remv linux-libc-dev [3.5.0-25.38]

    Reply
    1. Matt

      I saw the same behavior and the problem is caused by the naming of the linux-libc-dev package. I fixed the problem by changing the command dpkg -l linux-* to dpkg -l linux-headers* -l linux-image*.

      The full command would be dpkg -l linux-headers* -l linux-image* | awk '/^ii/{ print $2}' | grep -v -e `uname -r | cut -f1,2 -d"-"` | grep -e [0-9] | xargs sudo apt-get remove

      Reply
  32. Mark Preston

    Today, after 24 months of having old kernels pile up in /sda3 to the point that the OS failed, this post has removed the outdated kernels, and I have recovered 3 gig. Thank you very very much.

    Reply
  33. Patrick

    Hi Guys
    I get this error when using this
    E: Unmet dependencies. Try ‘apt-get -f install’ with no packages (or specify a solution).

    This may be because it failed to install correctly as the /boot is 100% full can you repost the solution showing where you would put just the one image to remove in order to clean space so i can run it again please
    Many thanks

    Reply
      1. Patrick

        Hi Linerd
        That worked a treat thanks. My problem was an incomplete linux header update to 3.2.0-34 due to not enough space and everything i did failed because of this. With the old solution i was able to remove older versions one at a time and create the space to complete the update and remove all of the old ones with your in one command

        Many thanks it was very much appreciated

        Reply
  34. a2461895

    Beware of what you’re doing if using this.
    This method is not fool-proof.
    On my system it wants to remove linux-libc-dev:amd64 too, which is a bad idea.

    Yes, it works on on 32-bits systems as the author already wrote, but I’m not so sure about 64-bits systems. There might be other packages that also meet the requirements and that are removed unexpectedly.

    Reply
  35. Gniourf

    With bash (don’t know/care about other shells), it’s better to quote the * in the dpkg command, to avoid an unwanted glob, just in case a file linux-something exists:
    dpkg -l linux-'*'

    Reply
  36. Marc Wäckerlin

    There’s a simpler way: Remove all but the bare necessary: You can add a plus (+) behind the packages you want to keep:

    First get your kernel type:

    ktype=$(uname -r | sed 's/.*-\(generic\|i386\|server\|common\|rt\|xen\|ec2\)/\1/')

    If you already know your kernel typ, you may set it directly, e.g.:

    ktype=generic

    Then use the variable “ktype” to remove everything but the actual kernel image:


    sudo apt-get remove --purge 'linux-(headers|image)-.*' linux-image-$(uname -r)+ linux-image-$ktype+ linux-$ktype+

    If you need the headers, keep them too:


    sudo apt-get remove --purge 'linux-(headers|image)-.*' linux-headers-$(uname -r)+ linux-headers-$(uname -r | sed s/-$ktype//)+ linux-headers-$ktype+ linux-image-$(uname -r)+ linux-image-$ktype+ linux-$ktype+

    Reply
    1. Linerd Post author

      My current kernel = 3.2.0-29-generic

      Using a dry run with your first command gives on my system
      [term]Remv linux-headers-3.2.0-23-generic [3.2.0-23.36]
      Remv linux-headers-3.2.0-23 [3.2.0-23.36]
      Remv linux-headers-3.2.0-24-generic [3.2.0-24.39]
      Remv linux-headers-3.2.0-24 [3.2.0-24.39]
      Remv linux-headers-3.2.0-25-generic [3.2.0-25.40]
      Remv linux-headers-3.2.0-25 [3.2.0-25.40]
      Remv linux-headers-3.2.0-26-generic [3.2.0-26.41]
      Remv linux-headers-3.2.0-26 [3.2.0-26.41]
      Remv linux-headers-3.2.0-27-generic [3.2.0-27.43]
      Remv linux-headers-3.2.0-27 [3.2.0-27.43]
      Remv nvidia-current [295.40-0ubuntu1.1]
      Remv linux-headers-generic [3.2.0.29.31]
      Remv linux-headers-3.2.0-29-generic [3.2.0-29.46]
      Remv linux-headers-3.2.0-29 [3.2.0-29.46]
      Remv linux-image-3.2.0-23-generic [3.2.0-23.36]
      Remv linux-image-3.2.0-24-generic [3.2.0-24.39]
      Remv linux-image-3.2.0-25-generic [3.2.0-25.40]
      Remv linux-image-3.2.0-26-generic [3.2.0-26.41]
      Remv linux-image-3.2.0-27-generic [3.2.0-27.43][/term]

      So I would lose my current kernel headers and for some reason, my nvidia driver. I don’t want to lose my nvidia driver.

      Whereas a dry run with my command gives on my system
      [term]Remv linux-headers-3.2.0-23-generic [3.2.0-23.36]
      Remv linux-headers-3.2.0-23 [3.2.0-23.36]
      Remv linux-headers-3.2.0-24-generic [3.2.0-24.39]
      Remv linux-headers-3.2.0-24 [3.2.0-24.39]
      Remv linux-headers-3.2.0-25-generic [3.2.0-25.40]
      Remv linux-headers-3.2.0-25 [3.2.0-25.40]
      Remv linux-headers-3.2.0-26-generic [3.2.0-26.41]
      Remv linux-headers-3.2.0-26 [3.2.0-26.41]
      Remv linux-headers-3.2.0-27-generic [3.2.0-27.43]
      Remv linux-headers-3.2.0-27 [3.2.0-27.43]
      Remv linux-image-3.2.0-23-generic [3.2.0-23.36]
      Remv linux-image-3.2.0-24-generic [3.2.0-24.39]
      Remv linux-image-3.2.0-25-generic [3.2.0-25.40]
      Remv linux-image-3.2.0-26-generic [3.2.0-26.41]
      Remv linux-image-3.2.0-27-generic [3.2.0-27.43][/term]

      Your final command gives the same result as mine.

      Does the “+” notation tell apt-get to install the package rather than remove it? I’m not familiar with that option.

      Reply
      1. Linerd Post author

        OK, I found it in the man page:

        If a plus sign is appended to the package name (with no intervening space), the identified package will be installed instead of removed.

        Reply
    1. Linerd Post author

      Does
      [term]sudo apt-get autoremove[/term]
      remove old kernels for you? It doesn’t on any of my systems.

      Reply
  37. kimme

    I use this script to clear my kernels


    #/bin/bash
    ls /boot/ | grep vmlinuz | sed 's@vmlinuz-@linux-image-@g' | grep -v `uname -r` > /tmp/kernelList
    for I in `cat /tmp/kernelList`
    do
    aptitude remove $I
    done
    rm -f /tmp/kernelList
    update-grub

    Reply
  38. bettyfurness

    superboer12 – great command, worked fine on my 64 bit Lucid. How would I modify this script to keep the last two kernels? I had .39, .40 and .41. After running this I had only .41. Booted OK but I always worry.

    Thanks!

    Reply
  39. Ubuntu Server

    Worked perfectly for me.
    After I finished, I ran /usr/sbin/update-grub just to be safe.

    Matt Locke – Nashville, TN

    Reply
  40. superboer12

    I modified it a little bit to keep both the running and the newest kernel.
    Thanks for the script!
    [code]
    rmkernel () {
    local cur_kernel=$(uname -r|sed ‘s/-*[a-z]//g’|sed ‘s/-386//g’)
    local kernel_pkg=”linux-(image|headers|ubuntu-modules|restricted-modules)”
    local meta_pkg=”${kernel_pkg}-(generic|i386|server|common|rt|xen|ec2|amd64)”
    local pre_kernel=$(echo ${cur_kernel} | tr ” \\\n | awk ‘BEGIN{FS=”-“;OFS=”-“} {print $1,$2-1}’)
    local latest_kernel=$(dpkg -l linux-* | awk ‘/^ii/{ print $2}’ | grep -v -e `uname -r | cut -f1,2 -d”-“` | grep -e [0-9] | tail -1 | cut -f3,4 -d”-“)
    aptitude purge -y $(dpkg -l | egrep $kernel_pkg | egrep -v “${cur_kernel}|${meta_pkg}|${latest_kernel}” | awk ‘{print $2}’)
    }

    rmkernel

    exit 0
    [/code]

    Reply
    1. superboer12

      Little correction:
      [term]
      #!/bin/bash

      rmkernel () {
      local cur_kernel=$(uname -r|sed 's/-*[a-z]//g'|sed 's/-386//g')
      local kernel_pkg="linux-(image|headers|ubuntu-modules|restricted-modules)"
      local meta_pkg="${kernel_pkg}-(generic|i386|virtual|server|common|rt|xen|ec2|amd64)"
      local latest_kernel=$(dpkg -l linux-* | awk '/^ii/{ print $2}' | grep -e [0-9] | tail -1 | cut -f3,4 -d"-")
      aptitude purge -y $(dpkg -l | egrep $kernel_pkg | egrep -v "${cur_kernel}|${meta_pkg}|${latest_kernel}" | awk '{print $2}')
      }

      rmkernel

      exit 0
      [/term]

      Reply
  41. R E Broadley

    Very nice, but this article seems to assume that you’re already running the OS with the latest kernel, so as this article goes, it will delete all kernels except the one currently running, which may be an old one.

    What would be a better command is if it deleted all kernels except the latest one (and perhaps also the one currently running).

    Speaking of which, why doesn’t ubuntu default to running the latest one? Despite installing kernel updates, mine’s still defaulting to an old one…

    Reply
  42. Santanu

    It’s always a good idea to keep the last kernel installed. So, I’d modify the rmkernel script to add this line for the previous version of kernel:
    [code]local pre_kernel=$(echo ${cur_kernel} | tr ” \\\n | awk ‘BEGIN{FS=”-“;OFS=”-“} {print $1,$2-1}’)[/code]
    and then add pre_kerne to the exclude list:
    [code]sudo aptitude purge $(dpkg -l | egrep $kernel_pkg | egrep -v “${cur_kernel}|${pre_kernel}|${meta_pkg}” | awk ‘{print $2}'[/code]

    For the one-liner:
    [code]dpkg -l linux-* | awk ‘/^ii/{ print $2}’ | grep -v -e `uname -r | cut -f1,2 -d”-“` -e `uname -r | gawk ‘BEGIN{FS=”-“;OFS=”-“} {print $1,$2-1}’` | grep -e [0-9][/code]

    Cheers!!

    Reply
  43. DKlann

    To take it one step further, you can purge all the old configuration files with the following (after completing the Big One Liner (above):

    dpkg -l ‘linux-*’ | awk ‘/^rc/{ print $2}’ | sudo xargs apt-get -y purge

    Thanks for this nice little ditty!

    Does anyone know how (or whether it makes sense) to delay the execution of the postrm.d scripts until after all the pieces are removed? It gets a little tiresome watching all those initramfs and zz-update-grub calls…

    Reply
    1. Linerd Post author

      Thanks for the tip. I didn’t know those rc status config files were still hanging around. However, when I try your command I get this type of error:
      [term]Package linux-image-2.6.32-27-generic is not installed, so not removed[/term]
      When I modify your command to:
      [term]dpkg -l ‘linux-*’ | awk ‘/^rc/{ print $2}’ | sudo xargs dpkg –purge[/term]
      it works.

      After doing some research, it looks like if I change my one-liner to purge instead of remove, then it should get rid of the config files as well and make this all moot, so I’m updating my post. I’ll install an older kernel and re-run the command to see if it works.

      Reply
  44. Vern

    “I’d be interested to know if it works just as well on a 64 bit system”
    Testing on Ubuntu Lucid amd64 system, and it works.

    Also someone posted this at Ubuntu forums a while back as a function script that works well:
    [term]

    rmkernel () {
            local cur_kernel=$(uname -r|sed 's/-*[a-z]//g'|sed 's/-386//g')
            local kernel_pkg="linux-(image|headers|ubuntu-modules|restricted-modules)"
            local meta_pkg="${kernel_pkg}-(generic|i386|server|common|rt|xen|ec2)"
            sudo aptitude purge $(dpkg -l | egrep $kernel_pkg | egrep -v "${cur_kernel}|${meta_pkg}" | awk '{print $2}')
    }
    
    rmkernel
    
    exit 0
    

    [/term]

    Reply
    1. Santanu

      It’s always a good idea to keep the previous kernel installed, in case you need to roll back. So, I’d add another line for previous kernel:

      local pre_kernel=$(echo ${cur_kernel} | tr ” \\\n | awk ‘BEGIN{FS=”-“;OFS=”-“} {print $1,$2-1}’)

      and then modify the ‘aptitude’ to add ‘pre_kernel’ to the exclude list:

      sudo aptitude purge $(dpkg -l | egrep $kernel_pkg | egrep -v “${cur_kernel}|${pre_kerne}|${meta_pkg}” | awk ‘{print $2}’)

      Cheers!!

      Reply
  45. Pingback: Links 8/10/2010: Linux Tablet Price Goes Down Under $200, Fedora 14 Beta Preview | Techrights

  46. carl801

    Hey, it works. Had to run update-grub, then because I’m using BURG, had to run update-burg. There oughta be a button somewhere for this command, eh?

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.