Cleanup Unused Linux Kernels in Ubuntu

I update Ubuntu with a very simple script I call apt-update that looks like this:

$ cat ./apt-update 
sudo apt-get update; sudo apt-get dist-upgrade; sudo apt-get autoremove

Nothing too crazy there. It updates the apt-get cache, performs the upgrade, and then removes all the residual junk that’s laying around. Well, almost all. If you do this enough, eventually you’ll see the following (assuming you’ve got the default motd Ubuntu script running and you’re logging in from a terminal):

=> /boot is using 86.3% of 227MB

This is because that script I mentioned doesn’t consider old kernel images to be junk. However, unless you’ve got an abnormal /boot partition, it doesn’t take too many old images to fill it up.

A quick Google search found Ubuntu Cleanup: How to Remove All Unused Linux Kernel Headers, Images and Modules. The solution on the page had exactly what I’m looking for, however, I couldn’t take it at face value. While the article offers an adequate solution, it doesn’t offer much explanation. The remainder of this article explains the details for this one-liner noted in the article above:

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

Note: Only run this if you’ve rebooted after installing a new kernel.

Ick. Let’s dig into what’s going on here. The pipe characters are chaining a bunch of commands together. Each command’s output becomes the input for the next. Given that, let’s walk through what’s going on in 3 steps.

Step 1 – List Linux Kernels: dpkg -l 'linux-*'

This one is fairly simple. Just pull up the man page for dpkg:

dpkg - package manager for Debian
...
dpkg-query actions
              -l, --list package-name-pattern...
                  List packages matching given pattern.

So, it should just list out the packages matching the pattern provided. Let’s try:

$ dpkg -l 'linux-*'
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version      Architecture Description
+++-==============-============-============-=================================
un  linux-doc-2.6.                     (no description available)
un  linux-doc-3.0.                     (no description available)
un  linux-doc-3.2.                     (no description available)
un  linux-doc-3.5.                     (no description available)
ii  linux-firmware 1.95         all          Firmware for Linux kernel drivers
un  linux-image                        (no description available)
un  linux-image-2.                     (no description available)
ii  linux-image-2. 2.6.38-11.50 amd64        Linux kernel image for version 2.
ii  linux-image-2. 2.6.38-8.42  amd64        Linux kernel image for version 2.
un  linux-image-3.                     (no description available)
rc  linux-image-3. 3.0.0-12.20  amd64        Linux kernel image for version 3.
rc  linux-image-3. 3.0.0-13.22  amd64        Linux kernel image for version 3.
rc  linux-image-3. 3.0.0-14.23  amd64        Linux kernel image for version 3.
rc  linux-image-3. 3.0.0-15.26  amd64        Linux kernel image for version 3.
rc  linux-image-3. 3.0.0-16.29  amd64        Linux kernel image for version 3.
ii  linux-image-3. 3.0.0-17.30  amd64        Linux kernel image for version 3.
rc  linux-image-3. 3.2.0-23.36  amd64        Linux kernel image for version 3.
rc  linux-image-3. 3.2.0-24.39  amd64        Linux kernel image for version 3.
rc  linux-image-3. 3.2.0-25.40  amd64        Linux kernel image for version 3.
rc  linux-image-3. 3.2.0-26.41  amd64        Linux kernel image for version 3.
rc  linux-image-3. 3.2.0-27.43  amd64        Linux kernel image for version 3.
rc  linux-image-3. 3.2.0-29.46  amd64        Linux kernel image for version 3.
rc  linux-image-3. 3.2.0-30.48  amd64        Linux kernel image for version 3.
rc  linux-image-3. 3.2.0-31.50  amd64        Linux kernel image for version 3.
ii  linux-image-3. 3.2.0-32.51  amd64        Linux kernel image for version 3.
ii  linux-image-3. 3.5.0-17.28  amd64        Linux kernel image for version 3.
ii  linux-image-3. 3.5.0-18.29  amd64        Linux kernel image for version 3.
ii  linux-image-3. 3.5.0-19.30  amd64        Linux kernel image for version 3.
ii  linux-image-3. 3.5.0-21.32  amd64        Linux kernel image for version 3.
ii  linux-image-3. 3.5.0-22.34  amd64        Linux kernel image for version 3.
ii  linux-image-3. 3.5.0-23.35  amd64        Linux kernel image for version 3.
ii  linux-image-ex 3.5.0-17.28  amd64        Linux kernel image for version 3.
ii  linux-image-ex 3.5.0-18.29  amd64        Linux kernel image for version 3.
ii  linux-image-ex 3.5.0-19.30  amd64        Linux kernel image for version 3.
ii  linux-image-ex 3.5.0-21.32  amd64        Linux kernel image for version 3.
ii  linux-image-ex 3.5.0-22.34  amd64        Linux kernel image for version 3.
ii  linux-image-ex 3.5.0-23.35  amd64        Linux kernel image for version 3.
ii  linux-image-ge 3.5.0.23.29  amd64        Generic Linux kernel image
ii  linux-image-se 3.5.0.23.29  amd64        Transitional package.
un  linux-initramf                     (no description available)
un  linux-kernel-h                     (no description available)
un  linux-kernel-l                     (no description available)
ii  linux-libc-dev 3.5.0-23.35  amd64        Linux Kernel Headers for developm
un  linux-restrict                     (no description available)
ii  linux-sound-ba 1.0.25+dfsg- all          base package for ALSA and OSS sou
un  linux-source-2                     (no description available)
un  linux-source-3                     (no description available)
un  linux-source-3                     (no description available)
un  linux-source-3                     (no description available)
un  linux-tools                        (no description available)

You can look at the man page for dpkg-query for more detail, but the items with an “i” for the 2nd character are currently installed. We’ll essentially want to dig through these installed old kernels and purge the ones we don’t want.

Step 2 – Show Unused Linux Kernels: sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'

This one is a little more tricky. We need to dissect it from the inside out. In the middle of that mess, you’ll see:

"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"

That’s essentially a command inside a command (kind of like the pipe concept, but injected in middle instead of the start of the input stream). We can drop the encapsulating “$( )” to see what this does:

$ uname -r
3.5.0-23-generic

… and then …

$ uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/"
3.5.0-23

As we see, this is using the uname command with the -r option to print the kernel release that’s active on our system. That next piece calls a powerful program called sed. It uses a regular expression to trim down the output of uname. If read in English, it says, “for the input given, try to first find as many characters as you can until you get to the last hyphen and remember them; if after the hyphen you find only non-numeric characters then replace the matched string with what was remembered, otherwise do nothing.” The regular expression is much more eloquent. :)

To better understand the remaining logic, we can reduce that original monster to the following by manually inserting “3.5.0-23″ where that uname/sed combo was before:

sed '/^ii/!d;/'"3.5.0-23"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'

This isn’t as bad as it first appears. It’s simply a chain of matches with /d or /!d, which mean delete the match or delete everything but the match respectively. Plus there’s one substitution. So …

/^ii/!d 

… means, delete all lines except those that start with ii

/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d

… means, delete all lines with the current kernel version in them (remember, this is equivalent to /'"3.5.0-23"'/d)

s/^[^ ]* [^ ]* \([^ ]*\).*/\1/

Consume all non-space characters, if any, followed by a space. Repeat. Remember the next set of non-space characters. Consume everything that follows. Replace everything with the remembered match.

/[0-9]/!d

… means, delete all lines except those with numbers.

My final output is the following:

linux-image-2.6.38-11-server
linux-image-2.6.38-8-server
linux-image-3.0.0-17-server
linux-image-3.2.0-32-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-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

Step 3 – Remove the Unused Kernels: xargs sudo apt-get -y purge

From the xargs man page, “xargs reads items from the standard input, delimited by blanks (which can be protected with double or single quotes or a backslash) or newlines, and executes the command (default is /bin/echo) one or more times with any initial-arguments followed by items read from standard input. Blank lines on the standard input are ignored.” In other words, xargs is going to let us issue the same command to each of those items listed in the last section.

The rest is fairly self explanatory. For every package listed, we’re going to ask apt-get to purge it, which the man page states means, “packages are removed and purged (any configuration files are deleted too).” The -y option means apt-get won’t ask for a confirmation. If you’re uneasy about the process, you might remove this for a dry-run, but given the cyclic nature of how we’re calling the command, it will abort (which is fine for a dry run, but you’ll have to add -y for it to work).

For completeness, sudo runs the purge as the super user.

All Together

Let’s try without -y first:

$ dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | xargs sudo apt-get purge
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be REMOVED:
  linux-image-2.6.38-11-server* linux-image-2.6.38-8-server* linux-image-3.0.0-17-server* linux-image-3.2.0-32-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-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*
0 upgraded, 0 newly installed, 14 to remove and 0 not upgraded.
After this operation, 1,359 MB disk space will be freed.
Do you want to continue [Y/n]? Abort.

Note the abort. This occurs automatically. Everything looks good here. Our current kernel isn’t in the list. Let’s do it! This time a lot more happens. I’ve inserted [SIMILAR OUTPUT DELETED] where the output is iterating over versions:

$ dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | xargs sudo apt-get -y purge
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be REMOVED:
  linux-image-2.6.38-11-server* linux-image-2.6.38-8-server* linux-image-3.0.0-17-server* linux-image-3.2.0-32-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-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*
0 upgraded, 0 newly installed, 14 to remove and 0 not upgraded.
After this operation, 1,359 MB disk space will be freed.
(Reading database ... 196310 files and directories currently installed.)
Removing linux-image-2.6.38-11-server ...
Examining /etc/kernel/postrm.d .
run-parts: executing /etc/kernel/postrm.d/initramfs-tools 2.6.38-11-server /boot/vmlinuz-2.6.38-11-server
update-initramfs: Deleting /boot/initrd.img-2.6.38-11-server
run-parts: executing /etc/kernel/postrm.d/zz-update-grub 2.6.38-11-server /boot/vmlinuz-2.6.38-11-server
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-3.5.0-23-generic
Found initrd image: /boot/initrd.img-3.5.0-23-generic
Found linux image: /boot/vmlinuz-3.5.0-22-generic
Found initrd image: /boot/initrd.img-3.5.0-22-generic
Found linux image: /boot/vmlinuz-3.5.0-21-generic
Found initrd image: /boot/initrd.img-3.5.0-21-generic
Found linux image: /boot/vmlinuz-3.5.0-19-generic
Found initrd image: /boot/initrd.img-3.5.0-19-generic
Found linux image: /boot/vmlinuz-3.5.0-18-generic
Found initrd image: /boot/initrd.img-3.5.0-18-generic
Found linux image: /boot/vmlinuz-3.5.0-17-generic
Found initrd image: /boot/initrd.img-3.5.0-17-generic
Found linux image: /boot/vmlinuz-3.2.0-32-generic
Found initrd image: /boot/initrd.img-3.2.0-32-generic
Found memtest86+ image: /memtest86+.bin
done
Purging configuration files for linux-image-2.6.38-11-server ...
Examining /etc/kernel/postrm.d .
run-parts: executing /etc/kernel/postrm.d/initramfs-tools 2.6.38-11-server /boot/vmlinuz-2.6.38-11-server
run-parts: executing /etc/kernel/postrm.d/zz-update-grub 2.6.38-11-server /boot/vmlinuz-2.6.38-11-server

[SIMILAR OUTPUT DELETED]

Note how the apt-get process even runs grub for you so your reboot menu is ready to go. Very nice!

Now let’s check our /boot partition, which was using 86% of 227 MB of storage space.

$ du -h /boot --max-depth=0
35M	/boot

Ah, only 35 M in use, i.e., 15%. Plenty of room for new kernel releases!

27 thoughts on “Cleanup Unused Linux Kernels in Ubuntu

  1. I was wondering how to properly enclose this in single quotes? I want to use this in an alias (much easier to main tain one .bashrc file than a bunch of independant scripts IMO) I wanted to do something like:
    alias update=’dpkg -l ‘linux-*’ | sed ‘/^ii/!d;/'”$(uname -r | sed “s/\(.*\)-\([^0-9]\+\)/\1/”)”‘/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d’ | xargs sudo apt-get -y purge && sudo apt-get update&& sudo apt-get dist-upgrade -y &&sudo apt-get autoremove -y &&sudo apt-get clean’

  2. this works for me:
    aptitude purge “~i~n(.*linux-image-3.* \!.*linux-image-$(uname -r).*)”
    at least while the 4.* kernels not yet released, which then i’d use “linux-image-4.*” in there instead.
    less is more ;)

    • Would loveto use…but seems there is a problem with the format:

      aptitude purge “~i~n(.*linux-image-3.* \!.*linux-image-$(uname -r).*)”

      robert@TKO-office:~$ aptitude purge “~i~n(.*linux-image-3.* \!.*linux-image-$(uname -r).*)”
      bash: syntax error near unexpected token `(‘

      Maybe just the wrong shell…

  3. Newer APT versions (differs by distro: Debian unstable & Ubuntu 13.04 should have it) include a tiny script which should automatically ensure that only ~3 kernel packages are kept back and the rest is “fair game” for the autoremover to kill. If not, I would like to encourage you to report a bug. :)

    Just advertising features (as reddit linked me here), not implying this is a bad advice – quiet a good idea to explain these “magic oneliners” indeed as running commands without knowing what they do can be quiet dangerous. But if I can make one suggestion: Avoid calling a program in these onliners with an autoconfirmation flag like you do above with “apt-get purge -y”. Letting the user double-check that the remove list is indeed correct is a lot better than the heart attack caused by one (or a hundred) removes which shouldn’t be in that list… [and shorter too: one press for Enter vs. "-y" ;) ]

    (for the technical more interested: APT is shipping a kernel-postinst script which is triggered (as the name implies) automatically after a kernel was installed. The script will ensure that the autoremover isn’t suggesting the remove of the currently running kernel, the kernel installed just now and the newest kernel)

    • Good to know. Thanks for the note about APT.

      FYI, I agree on -y. That’s why I recommended a dry run without it. However, in this case, it’s necessary for the command to run given the cyclic nature of the commands. If you omit it, you’ll get an abort.

  4. It’s better to keep /boot/grub under a separate partition rather than the whole of /boot.

    /boot/grub has all of the required GRUB configuration and other files, and they don’t take up a lot of space. Even if you remove the distro from which you originally installed and configured GRUB, you can remove that distro and still be able to boot (I think).

    Kernels are large, stored under /boot and are mostly distro-specific, so it’s better to keep it on the same partition as root.

  5. I have been trying for about three weeks now to find away to clear whatever must be cleared from my boot file which is full. I have tried various command lines in my terminal, including the one provided above ie:
    $ dpkg -l ‘linux-*’ | sed ‘/^ii/!d;/'”$(uname -r | sed “s/\(.*\)-\([^0-9]\+\)/\1/”)”‘/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d’ | xargs sudo apt-get -y purge

    and I get this:
    jeremy@jeremy-desktop:~$ $ dpkg -l ‘linux-*’ | sed ‘/^ii/!d;/'”$(uname -r | sed “s/\(.* \)-([^0-9]\+\)/\1/”)”‘/d;s/^[^ ]* [^ ] \([^ ]*\).*/\1/;/[0-9]/!d’ | xargs sudo apt-get -y purge
    sed: -e expression #1, char 25: Unmatched ) or \)
    $: command not found

    [1]+ Stopped $ dpkg -l ‘linux-*’ | sed ‘/^ii/!d;/'”$(uname -r | sed “s/\(.* \)-([^0-9]\+\)/\1/”)”‘/d;s/^[^ ]* [^ ] \([^ ]*\).*/\1/;/[0-9]/!d’ | xargs sudo apt-get -y purge
    jeremy@jeremy-desktop:~$ $ dpkg -l ‘linux-*’ | sed ‘/^ii/!d;/'”$(uname -r | sed “s/\(.*\)-\([^0-9]\+\)/\1/”)”‘/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d’ | xargs sudo apt-get -y purge
    $: command not found

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

    Most of the advice /coments in these threads (and this thread) go completely over my head, and the info that happens in my terminal when I hit enter is also total GREEK to me.

    i have also tried to use the advice at
    http://askubuntu.com/questions/89710/how-do-i-free-up-more-space-in-boot
    (which I also dont understand)

    and
    http://askubuntu.com/questions/270916/boot-folder-is-full-so-cannot-install-updates
    (which I also dont understand)

    and
    http://ubuntugenius.wordpress.com/2011/01/08/ubuntu-cleanup-how-to-remove-all-unused-linux-kernel-headers-images-and-modules/
    (which I also dont understand)

    and to be honest, I dont know what I am doing except blindly following the command lines suggested. I do not understand even WHY a Linux Ubuntu OS cannot automatically update without accumulating junk in the boot file. Why can old stuff be removed as part of the next update?

    Please could you provide a simple cut and paste command that I can just paste into my terminal , hit enter, and reboot with a clear boot file?

    and
    http://askubuntu.com/questions/171209/my-boot-partition-hit-100-and-now-i-cant-upgrade-cant-remove-old-kernels-to

    I have not yet looked at this:
    https://gist.github.com/jbgo/5016064

    but I have hit a point of saturation/frustration/insanity/confusion in this matter and now must ask help directly.

    This is my list of stuff in the boot file:
    /boot/config-3.5.0-31-generic
    /boot/config-3.5.0-32-generic
    /boot/config-3.5.0-34-generic
    /boot/config-3.5.0-36-generic
    /boot/config-3.5.0-37-generic
    /boot/config-3.5.0-39-generic
    /boot/config-3.5.0-40-generic
    /boot/initrd.img-3.5.0-31-generic
    /boot/initrd.img-3.5.0-32-generic
    /boot/initrd.img-3.5.0-34-generic
    /boot/initrd.img-3.5.0-36-generic
    /boot/initrd.img-3.5.0-37-generic
    /boot/initrd.img-3.5.0-39-generic
    /boot/initrd.img-3.5.0-40-generic
    /boot/memtest86+.bin
    /boot/memtest86+_multiboot.bin
    /boot/System.map-3.5.0-31-generic
    /boot/System.map-3.5.0-32-generic
    /boot/System.map-3.5.0-34-generic
    /boot/System.map-3.5.0-36-generic
    /boot/System.map-3.5.0-37-generic
    /boot/System.map-3.5.0-39-generic
    /boot/System.map-3.5.0-40-generic
    /boot/vmlinuz-3.5.0-31-generic
    /boot/vmlinuz-3.5.0-32-generic
    /boot/vmlinuz-3.5.0-34-generic
    /boot/vmlinuz-3.5.0-36-generic
    /boot/vmlinuz-3.5.0-37-generic
    /boot/vmlinuz-3.5.0-39-generic
    /boot/vmlinuz-3.5.0-40-generic

    what must I do now?
    Thanks
    Jeremy

    • Make sure you don’t copy the dollar sign in front.
      so the command would be

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

  6. Pingback: [Ubuntu] Remove Old (Unused) Kernel | Wishsoft .Net

  7. I made the stupid mistake in upgrading the kernel and before boot running this command which delete the latest kernel.
    Luckily i noticed before booting. :)

  8. Well, but I see that on 32-bit system, the script deletes also current version non-PAE kernel (when running pae, or vice versa), which may, or may not, be welcome.
    I will better purge manually, using the part of the script to list kernels, but running apt purge one-by-one just stupid copy&paste. That way, I may keep one or two older kernels, just for backup.
    Anyway, many thanks for the explanations.. great to use, but anyway, there is zero chane that I will remember any part of it, so I will return again and again to copy them from here :-)

  9. Sorry, I missed something, only headers with current version are on purge list. I do not know whether they should go or not.
    List is way too long to copy and paste though..
    Well, divide et impera: instead of pipe, Ive used output redirect to file, e.g >kernelstopurge, nano edited that list so I deleted every line containing .5x version (keeping .51 52 .53 and 54 kernels for now, pae and non pae), and pass it forward just by
    $ cat kernelstopurge |xargs apt-get -y purge
    Feeling much better having control over the task.

  10. Pingback: Verwijderen van oude kernels on Unbuntu « Blog van Peter Spekreijse

  11. Hi Mark,

    I use your command, but I have got this message ??

    Reading package lists… Done
    Building dependency tree
    Reading state information… Done
    You might want to run ‘apt-get -f install’ to correct these:
    The following packages have unmet dependencies:
    linux-headers-generic : Depends: linux-headers-3.2.0-55-generic but it is not going to be installed
    linux-headers-generic-lts-quantal : Depends: linux-headers-3.5.0-43-generic but it is not going to be installed
    linux-image-generic-lts-quantal : Depends: linux-image-3.5.0-42-generic but it is not going to be installed
    E: Unmet dependencies. Try ‘apt-get -f install’ with no packages (or specify a solution).

    How can I do, please help me

  12. Hello.
    I have problem :(
    224M /boot

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

    Output:
    dependencies-error linux-headers-generic-lts-quantal, missing linux-headers-3.5.0-43-generic

    Proposed solutions:
    apt-get -f install

    Output:
    E: Sub-process /usr/bin/dpkg returned an error code (1)

    Reason:
    Error in /var/cache/apt/archives/linux-image-3.5.0-43-generic_3.5.0-43.66~precise1_amd64.deb (–unpack)
    – full buffer ./boot/vmlinuz-3.5.0-43-generic

    Prease help me!

  13. I find solution:
    dpkg -l linux-image-\* | grep ^ii

    remove oldest boot:
    apt-get purge linux-image-3.5.0-32-generic

    or remove all old boot:
    apt-get remove linux-image-3.5.0-{32,34,36,37,39,40,41,42}-generic

    Next:
    apt-get autoremove
    reboot

    After reboot:
    29M /boot

  14. Hi Mark,

    You say that you must reboot before executing this oneliner, so the last kernel applies to the system. This isn’t always possible (servers, you know), so I’d wanted to add one more feature to this one: don’t remove the last kernel version (which will be applied in the next reboot).

    I’ve came up with this:
    dpkg -l ‘linux-*’ | sed ‘/^ii/!d;/'”$(uname -r | sed “s/\(.*\)-\([^0-9]\+\)/\1/”)”‘/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d’ > out.txt ; grep “$(cat out.txt | cut -d – -f3-4 | sort | uniq | head -n -1)” out.txt | xargs apt-get -y remove –purge ; rm out.txt

    I know, it’s ugly because I’m using a temp file, could you help me here?

    Regards

  15. Tnx! You saved my day. The long command didn’t do all of the job in one sweep, but your explanation of the different parts helped me to track down what was left over. And then ‘sudo apt-get purge’ could do the last bits.

  16. @Mark McBride: Thank you for providing the original link in your article and thank you for the explanation of the command.

    BTW, have you told Otis Elevator about your suggestion for a ‘cancel’ button? My toaster has a cancel button.

  17. Pingback: Cleanup unused linux kernels in ubuntu | mjay|me

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>