如何删除旧内核版本以清理启动菜单?

每次我安装一个新的Linux内核时,它都会留在grub_config中,每次启动菜单都会更长。

我知道我可以手动搜索已安装的软件包并将其删除。

Ubuntu是否提供了更简单的方法来清理它们或阻止它们显示在引导列表中?

16.04和更新版本的Ubuntu

 sudo apt autoremove 

此命令删除自动安装的包以解决依赖关系,但现在不再依赖它们。 这包括旧版本的linux-headers-*linux-image-* 。 (这个过程也很聪明,留下一个备用版本的内核作为后备!)

11.10和更新版本的Ubuntu

GRUB2及其所有内核的显示

安装在Ubuntu中的最新版本的Grub2会自动显示最新内核并隐藏您可能已安装的旧内核。

GNU GRUB

如果你没有看到你的grub – 那么记得在启动时按Shift键

如您所见,仅显示最新的内核。

如果选择显示的选项(按Enter键 ),则所有旧内核都可见并可从中进行引导。

GNU GRUB以前的版本

如何永久删除旧内核

首先使用最新的可用内核启动。

有许多方法可以删除旧内核。 就个人而言,我不会触及Computer Janitor,因为我们承认会破坏您的计算机并给出建议。

突触

另一种选择是Synapticsudo apt install synaptic

搜索linux-image ,右键单击内核并选择完全删除,最后单击Apply按钮删除内核。

突触包管理器

重复搜索,但这次是针对linux-header – 您可以删除先前选择的内核映像的关联头。

Synaptic虽然不会尝试validation你要删除的内容…你可能无意中删除了你的最新内核 – 甚至通过这个工具删除了所有的内核,让你无法启动Ubuntu

请记住检查您使用的内核类型:

 uname -r 

结果类似于:

终端<uname -r/>“></p>
<p> 记住结果和数字 – 确保不删除相应的图像或标题。 </p>
<h1> 建议 </h1>
<p> 我的建议是保留至少两个或最好是三个内核,包括最新内核。 建议的原因是,至少有一个/两个其他内核可以启动,如果出于任何原因,您无法启动最新内核或引入回归function,例如无线function损坏。 </p>

</div><!-- #comment-## -->
<div class=

首先,重新启动系统以确保它使用最新的内核。 然后打开终端并检查当前内核:

 uname -r 

不要删除这个内核!

接下来,键入以下命令以查看/列出系统上所有已安装的内核。

 dpkg --list | grep linux-image 

找到低于当前内核的所有内核。 当您知道要删除的内核时,请在下面继续删除它。 运行以下命令以删除您选择的内核。

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

最后,运行以下命令更新grub2

 sudo update-grub2 

重新启动系统。

我的单线程删除旧内核(这也释放了磁盘空间)

 dpkg --list | grep linux-image | awk '{ print $2 }' | sort -V | sed -n '/'`uname -r`'/q;p' | xargs sudo apt-get -y purge 

解释(记住, |使用上一个命令的输出作为下一个命令的输入)

  • dpkg --list列出了所有已安装的软件包
  • grep linux-image查找已安装的linux映像
  • awk '{ print $2 }'只输出第二列(这是包名)
  • sort -V按版本号按顺序放置项目
  • sed -n '/'`uname -r`'/q;p'打印当前内核之前的行
  • xargs sudo apt-get -y purge清除找到的内核

展开sed调用:

  • -n告诉sed要安静
  • `uname -r`输出当前安装的内核版本 – 我们将其包含在反引号中,以便输出包含在命令中(您可能还会将其视为$(uname -r)
  • /something/q表示匹配’something’时停止(在这种情况下,某些东西是uname -r输出) – /环绕正则表达式
  • p是打印
  • ; 是命令separtor,所以/something/q;p表示匹配时退出,否则打印

总而言之, sed -n '/'`uname -r`'/q;p'打印行,直到它与当前内核名称匹配。

如果你是偏执狂(像我一样),你可以让最后一部分xargs echo sudo apt-get -y purge以便打印清除旧内核的命令,然后你可以在运行之前检查是否包含任何意外的内容。


修改版本以删除标题:

 dpkg --list | grep 'linux-image' | awk '{ print $2 }' | sort -V | sed -n '/'"$(uname -r | sed "s/\([0-9.-]*\)-\([^0-9]\+\)/\1/")"'/q;p' | xargs sudo apt-get -y purge dpkg --list | grep 'linux-headers' | awk '{ print $2 }' | sort -V | sed -n '/'"$(uname -r | sed "s/\([0-9.-]*\)-\([^0-9]\+\)/\1/")"'/q;p' | xargs sudo apt-get -y purge 

注意: sed调用已修改。 "$(uname -r | sed "s/\([0-9.-]*\)-\([^0-9]\+\)/\1/")"仅提取版本(例如“ 3.2.0-44“),没有”-generic“或类似于uname -r


一体化版本删除图像和标题(结合上面的两个版本):

 echo $(dpkg --list | grep linux-image | awk '{ print $2 }' | sort -V | sed -n '/'`uname -r`'/q;p') $(dpkg --list | grep linux-headers | awk '{ print $2 }' | sort -V | sed -n '/'"$(uname -r | sed "s/\([0-9.-]*\)-\([^0-9]\+\)/\1/")"'/q;p') | xargs sudo apt-get -y purge 

Ubuntu 16.04+:

 $ sudo apt autoremove ... The following packages will be REMOVED: linux-headers-4.4.0-57 linux-headers-4.4.0-57-generic linux-image-4.4.0-57-generic linux-image-extra-4.4.0-57-generic linux-tools-4.4.0-57 linux-tools-4.4.0-57-generic 

Ubuntu 15.10及以下版本:

我发现这是最简单,最快捷的方式。 它保留了最新的内核以及另外两个:

 sudo apt-get install bikeshed sudo purge-old-kernels 

要更改保留的其他内核的数量:

 sudo purge-old-kernels --keep 3 

从Grub 2条目中删除条目应通过编辑或删除/etc/grub.d文件夹中的文件来删除条目。 /boot/grub/grub.cfg文件是只读的,通常不需要编辑。

内核太多了?

  • 如果您不确定当前使用的内核,请在终端类型uname -r中使用

  • 通过APT删除的内核(Synaptic,“apt-get remove”等)将自动更新grub.cfg,无需用户操作。

  • Ubuntu-Tweak是一款安全且易于使用的GUI应用程序,可用于删除内核(和菜单条目)。

  • 安装ubuntu tweak

  • Ubuntu-Tweak将在Applications> System Tools下提供。

删除较旧的内核条目

  • 选择左侧的“Package Cleaner”和右侧面板中的“Clean Kernel”。

  • 按右下角的“解锁”按钮,输入您的密码。

  • 从显示的列表中选择要删除的内核映像和标题。 未列出正在使用的内核。

  • 按右下角的“清理”按钮删除选定的内核映像和标题。

从Grub菜单中删除操作系统

  • 一旦以root身份运行“update-grub”,也将从菜单中删除已从计算机中删除的其他操作系统。

  • 菜单项通过脚本放置在Grub2菜单上。 如果您不想在菜单中输入其他操作系统,请禁用/etc/grub.d/30_osprober

  • 运行此命令以停止脚本运行
    sudo chmod -x /etc/grub.d/30_os-prober

  • / etc / default / grub中的DISABLE_30_OS-PROBER =’true’

从Grub菜单中删除Memtest86 +
sudo chmod -x /etc/grub.d/20_memtest86+

  • 运行update-grub命令以允许将更改合并到grub.cfg中

资源

注意:内核更新后,会在GRUB菜单中添加一个新条目。如果需要,您可以删除旧条目。但是,大多数有经验的用户会建议您保留至少一个备用条目,以防升级出现问题而您需要引导较旧的内核版本以进行故障排除。

删除内核条目的替代方法(10.04之前)

对于GRUB而不是GRUB2

startupmanager 安装startupmanager

您可以在系统>>管理>>下找到它 替代文字
替代文字
您在第二个屏幕截图中看到,您可以选择要显示的内核数量? 我通常只将它保持在1,但是当我获得内核升级时,我总是在重新启动之前将其更改为2,因此如果新内核的硬件出现问题,我可以选择较旧的内核。 一旦我知道新内核运行良好,我就将它改回1。

纯粹的命令行,这将删除除当前和第二最新电流之外的所有电流(通过下面head命令中的“-2”):

 OLD=$(ls -tr /boot/vmlinuz-* | head -n -2 | cut -d- -f2- | awk '{print "linux-image-" $0 " linux-headers-" $0}' ) if [ -n "$OLD" ]; then apt-get -qy remove --purge $OLD fi apt-get -qy autoremove --purge 

更新:现在不推荐使用 purge-old-kernels

我制作了一个脚本,即使在棘手的条件下也可以清除内核。 它被称为linux-purge ,你可以在这里找到它。

如果您只想清除比当前使用的内核更旧的内核(和相关软件包),那么当系统没有损坏时,您可以使用此脚本 。

还有一个Ubuntu文档页面,我在这里有关于删除旧内核的贡献。

您可以按照Ubuntu Wiki上的自动安全更新文章的“无人参与升级”包部分来执行此操作。

您需要在/etc/apt/apt.conf.d/50unattended-upgrades文件中更改以下行;

 //Unattended-Upgrade::Remove-Unused-Dependencies "false"; 

 Unattended-Upgrade::Remove-Unused-Dependencies "true"; 

自动删除旧包,包括内核。

同时删除或评论该行

 "^linux-image.*"; 

在文件/etc/apt/apt.conf.d/01autoremove的“NeverAutoRemove”部分中

Ubuntu已经提供的最快/更简单的方法(至少从12.04开始适用)是apt-get 。 如果您希望删除所有未使用的旧内核版本,请执行以下操作(除了您之前未使用的旧版本。这是为了确保如果当前内核版本以某种方式失败,您可以选择回到以前的状态)。 请执行下列操作:

 sudo apt-get autoclean 

这将消除您可能拥有的任何旧文件(包括内核版本)。 请注意,如果您有许多旧版本,则需要一段时间,因为必须确保删除内核版本没有问题。 对我来说,删除最后12个内核版本大约需要2分钟。 您还可以执行以下操作:

 sudo apt-get clean 

这将消除下载并存储在apt的缓存文件夹中的所有内容。 最后你有:

 sudo apt-get autoremove 

这将检查任何未使用的包,并在必要时删除它们。 这对于任何安装的应用程序不再需要的库和依赖包非常有用。

10.04 GUI方法

Computer Janitor可以清理旧内核,我相信默认安装在Ubuntu中(但不是Kubuntu)。

GRUB 1,如果你正在使用它,在/boot/grub/menu.lst有一个选项来指定它应该最多显示多少个内核。 据我所知,GRUB 2没有。

要弄清楚安装了哪些内核和头文件

 dpkg -l | grep linux-image dpkg -l | grep linux-headers 

然后您可以逐个或一起删除它们,只需确保保持最新状态。

还有一些方便的命令和脚本可以自动删除。

http://ubuntuforums.org/showthread.php?t=1658648

以下声明删除所有未使用的内核和标头:

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

以下是在18.04.1上运行时发生的情况:

 ~$ dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9] \+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'|grep -E "(image|headers|modules)" | xargs sudo apt-get -y purge Reading package lists... Done Building dependency tree Reading state information... Done The following packages will be REMOVED: linux-headers-4.15.0-33* linux-headers-4.15.0-33-generic* linux-headers-4.15.0-34* linux-headers-4.15.0-34-generic* linux-image-4.15.0-33-generic* linux-image-4.15.0-34-generic* linux-modules-4.15.0-33-generic* linux-modules-4.15.0-34-generic* linux-modules-extra-4.15.0-33-generic* linux-modules-extra-4.15.0-34-generic* 0 upgraded, 0 newly installed, 10 to remove and 1 not upgraded. After this operation, 671 MB disk space will be freed. (Reading database ... 227403 files and directories currently installed.) Removing linux-headers-4.15.0-33-generic (4.15.0-33.36) ... Removing linux-headers-4.15.0-33 (4.15.0-33.36) ... Removing linux-headers-4.15.0-34-generic (4.15.0-34.37) ... Removing linux-headers-4.15.0-34 (4.15.0-34.37) ... Removing linux-modules-extra-4.15.0-33-generic (4.15.0-33.36) ... Removing linux-image-4.15.0-33-generic (4.15.0-33.36) ... /etc/kernel/postrm.d/initramfs-tools: update-initramfs: Deleting /boot/initrd.img-4.15.0-33-generic /etc/kernel/postrm.d/zz-update-grub: Generating grub configuration file ... Found linux image: /boot/vmlinuz-4.15.0-36-generic Found initrd image: /boot/initrd.img-4.15.0-36-generic Found linux image: /boot/vmlinuz-4.15.0-34-generic Found initrd image: /boot/initrd.img-4.15.0-34-generic Adding boot menu entry for EFI firmware configuration done Removing linux-modules-extra-4.15.0-34-generic (4.15.0-34.37) ... Removing linux-image-4.15.0-34-generic (4.15.0-34.37) ... I: /vmlinuz.old is now a symlink to boot/vmlinuz-4.15.0-36-generic I: /initrd.img.old is now a symlink to boot/initrd.img-4.15.0-36-generic /etc/kernel/postrm.d/initramfs-tools: update-initramfs: Deleting /boot/initrd.img-4.15.0-34-generic /etc/kernel/postrm.d/zz-update-grub: Generating grub configuration file ... Found linux image: /boot/vmlinuz-4.15.0-36-generic Found initrd image: /boot/initrd.img-4.15.0-36-generic Adding boot menu entry for EFI firmware configuration done Removing linux-modules-4.15.0-33-generic (4.15.0-33.36) ... Removing linux-modules-4.15.0-34-generic (4.15.0-34.37) ... (Reading database ... 156180 files and directories currently installed.) Purging configuration files for linux-image-4.15.0-34-generic (4.15.0-34.37) ... Purging configuration files for linux-modules-4.15.0-33-generic (4.15.0-33.36) ... dpkg: warning: while removing linux-modules-4.15.0-33-generic, directory '/lib/modules/4.15.0-33-generic' not empty so not removed Purging configuration files for linux-modules-4.15.0-34-generic (4.15.0-34.37) ... Purging configuration files for linux-image-4.15.0-33-generic (4.15.0-33.36) ... Purging configuration files for linux-modules-extra-4.15.0-34-generic (4.15.0-34.37) ... Purging configuration files for linux-modules-extra-4.15.0-33-generic (4.15.0-33.36) ... ~$ uname -r 4.15.0-36-generic 

为了删除旧的Linux映像内核,首先在要保留的内核中启动。

您还可以使用命令uname -r检查内核版本,这样就不会错误地删除错误的内核版本。

现在转到synaptic包管理器并搜索linux-image并删除旧版本,除了upper命令显示的版本。 一般来说,我更喜欢使用最新版本。

现在当你重新启动时,你会看到一个更干净的grub菜单。

您可以安装ubuntu-tweak ,然后转到应用程序 – >系统工具 – > ubuntu tweak和

在此处输入图像描述 单击包清理并清理内核。 它不显示当前使用的内核,因此您将始终是安全的。

就个人而言,我喜欢使用Synaptic 。 它让我对正在发生的事情感到更加安全。 我使用的唯一一个可以删除旧内核的应用程序是Ubuntu Tweak 。

如何删除不使用的内核:

  • 打开UbuntuTweak
  • 单击左侧窗格中“应用程序”下的“包清洁程序”
  • 在“清洁视图”的右侧按“清洁内核”
  • 选择所有内核 – 我认为正在使用的内核未列出,但以防万一在终端中运行uname -a

您可以使用Synaptic卸载旧内核( linux-image-...软件包),这将从启动菜单中删除它们。 注意不要删除正在运行的内核(可以使用uname -r检查其版本)。

请记住,如果出现问题,拥有一个或两个旧版本可以帮助您排除故障。

或者,您可以手动编辑/删除条目( gksu gedit /boot/grub/grub.cfg ),但是当您更新到较新的内核时,它们将被重新生成。 如果您正考虑删除recovery mode选项 – 请不要。 如果你打破阻止你开机的东西,他们可以派上用场。


请参阅此页面。

这是一个纯粹的命令行解决方案。

首先生成除当前运行的内核之外的所有已安装内核版本的列表:

 dpkg-query -W -f='${Package}\n' | grep -f <(ls -1 /boot/vmlinuz* | cut -d- -f2,3 | grep -v $(uname -r | cut -d- -f1,2)) 

或者生成除最后两个之外的所有已安装内核版本的列表:

 dpkg-query -W -f='${Package}\n' | grep -f <(ls -1 /boot/vmlinuz* | cut -d- -f2,3 | sort -V | head -n -2) 

检查列表。 确保要保留的内核版本不属于列表。 使用命令uname -r查看当前运行的内核的版本。

如果您对结果满意,可以使用apt-get删除包。

First a dry run (using the first generator as example):

 sudo apt-get --dry-run purge $( dpkg-query -W -f='${Package}\n' | grep -f <(ls -1 /boot/vmlinuz* | cut -d- -f2,3 | grep -v $(uname -r | cut -d- -f1,2))) 

Then a real run:

 sudo apt-get purge $( dpkg-query -W -f='${Package}\n' | grep -f <(ls -1 /boot/vmlinuz* | cut -d- -f2,3 | grep -v $(uname -r | cut -d- -f1,2))) 

If you want to automate the process then add the --yes parameter:

 sudo apt-get --yes purge $( ...) 

The advantage of this answer is native Ubuntu Bash is used without installing third-party applications. Users of custom kernels who didn’t use apt or dpkg can change this bash script to suit their needs. This answer is based on ( How to selectively purge old kernels all at once ).

Zenity based solution

Zenity provides a nice GUI interface to the terminal to process a list and select items with radio-buttons :

rm-kernels 1

As the title indicates the current kernel you booted with cannot be removed and isn’t included in the list. The size reported is how much will be saved in /boot directory. More is saved on your disk because kernel binaries reside in other areas too. July 27, 2017 note: The directories /usr/src/*kernel_version* and /lib/modules/*kernel_version* are now included as well.

The Modified Date is discovered using the stat command. On my system that date is “touched” every time the kernel is booted using this ( How do you find out when a specific kernel version was last booted? ) cron reboot script. However, on your system the date will be the kernel release date, not the last time you booted it.

apt-get purge gives you chance to abort

You are given a final opportunity to view everything that will be purged and see the total disk space (somewhat misleading) that will be recovered:

 The following packages will be REMOVED: linux-headers-4.7.1-040701* linux-headers-4.7.1-040701-generic* linux-headers-4.7.2-040702* linux-headers-4.7.2-040702-generic* linux-headers-4.7.3-040703* linux-headers-4.7.3-040703-generic* linux-headers-4.8.1-040801* linux-headers-4.8.1-040801-generic* linux-headers-4.8.10-040810* linux-headers-4.8.10-040810-generic* linux-headers-4.8.11-040811* linux-headers-4.8.11-040811-generic* linux-headers-4.8.4-040804* linux-headers-4.8.4-040804-generic* linux-headers-4.8.5-040805* linux-headers-4.8.5-040805-generic* linux-image-4.7.1-040701-generic* linux-image-4.7.2-040702-generic* linux-image-4.7.3-040703-generic* linux-image-4.8.1-040801-generic* linux-image-4.8.10-040810-generic* linux-image-4.8.11-040811-generic* linux-image-4.8.4-040804-generic* linux-image-4.8.5-040805-generic* 0 upgraded, 0 newly installed, 24 to remove and 2 not upgraded. After this operation, 2,330 MB disk space will be freed. Do you want to continue? [Y/n] 

The Code

Copy this code to an executable file named rm-kernels in /usr/local/bin :

 #!/bin/bash # NAME: rm-kernels # PATH: /usr/local/bin # DESC: Provide zenity item list of kernels to remove # DATE: Mar 10, 2017. Modified Jul 28, 2017. # NOTE: Will not delete current kernel. # With 10 kernels on an SSD, empty cache from sudo prompt (#) using: # # free && sync && echo 3 > /proc/sys/vm/drop_caches && free # First time for `du` 34 seconds. # Second time for `du` 1 second. # PARM: If any parm 1 passed use REAL kernel size, else use estimated size. # By default `du` is not used and estimated size is displayed. # Must be running as sudo if [[ $(id -u) != 0 ]]; then zenity --error --text "root access required. Use: sudo rm-kernels" exit 99 fi OLDIFS="$IFS" IFS="|" choices=() current_version=$(uname -r) for f in /boot/vmlinuz* do if [[ $f == *"$current_version"* ]]; then continue; fi # skip current version [[ $f =~ vmlinuz-(.*) ]] v=${BASH_REMATCH[1]} # example: 4.9.21-040921-generic v_main="${v%-*}" # example: 4.9.21-040921 # Kernel size in /boot/*4.9.21-040921-generic* s=$(du -ch /boot/*-$v* | awk '/total/{print $1}') if [[ $# -ne 0 ]] ; then # Was a parameter passed? if [[ -d "/usr/src/linux-headers-"$v_main ]] ; then # Kernel headers size in /usr/src/*4.9.21-040921* s2=$(du -ch --max-depth=1 /usr/src/*-$v_main* | awk '/total/{print $1}') else s2="0M" # Linux Headers are not installed fi # Kernel image size in /lib/modules/4.9.21-040921-generic* s3=$(du -ch --max-depth=1 /lib/modules/$v* | awk '/total/{print $1}') else # Estimate sizof of optional headers at 125MB and size of image at 220MB if [[ -d "/usr/src/linux-headers-"$v_main ]] ; then s2="125M" else s2="0M" # Linux Headers are not installed fi s3="220M" fi # Strip out "M" provided by human readable option of du and add 3 sizes together s=$(( ${s//[^0-9]*} + ${s2//[^0-9]*} + ${s3//[^0-9]*} )) t=$(( t + s )) s=$s" MB" d=$(date --date $(stat -c %y $f) '+%b %d %Y') # Last modified date for display choices=("${choices[@]}" false "$v" "$d" "$s") done # adjust width & height below for your screen 640x480 default for 1920x1080 HD screen # also adjust font="14" below if blue text is too small or too large choices=(`zenity \ --title "rm-kernels - Total: $t MB excluding: $current_version" \ --list \ --separator="$IFS" \ --checklist --multiple \ --text 'Check box next to kernel(s) to remove' \ --width=640 \ --height=480 \ --column "Select" \ --column "Kernel Version Number" \ --column "Modified Date" \ --column " Size " \ "${choices[@]}"`) IFS="$OLDIFS" i=0 list="" for choice in "${choices[@]}" ; do if [ "$i" -gt 0 ]; then list="$list- "; fi # append "-" from last loop ((i++)) short_choice=$(echo $choice | cut -f1-2 -d"-") header_count=$(find /usr/src/linux-headers-$short_choice* -maxdepth 0 -type d | wc -l) # If -lowlatency and -generic are purged at same time the _all header directory # remains on disk for specific version with no -generic or -lowlatency below. if [[ $header_count -lt 3 ]]; then # Remove all wxy-zzz headers list="$list""linux-image-$choice- linux-headers-$short_choice" else # Remove wxy-zzz-flavour header only, ie -generic or -lowlatency list="$list""linux-image-$choice- linux-headers-$choice" fi done if [ "$i" -gt 0 ] ; then apt-get purge $list fi 

NOTE: You need sudo permission to create the file so use:

 gksu gedit /usr/local/bin/rm-kernels 

To make file executable use:

 sudo chmod +x /usr/local/bin/rm-kernels 

Server Version

rm-kernels-server is the server version to selectively delete kernels all at once. Instead of a GUI (graphical) dialog box a text-based dialog box is used to select kernels to purge.

  • Before running the script you need to install the dialog function using:

    sudo apt install dialog

Dialog is in the default Ubuntu Desktop installation but not in Ubuntu Server.

Sample screen

rm-kernels-server 1

rm-kernels-server bash code

 #!/bin/bash # NAME: rm-kernels-server # PATH: /usr/local/bin # DESC: Provide dialog checklist of kernels to remove # Non-GUI, text based interface for server distro's. # DATE: Mar 10, 2017. Modified Jul 28, 2017. # NOTE: Will not delete current kernel. # With 10 kernels on an SSD, empty cache from sudo prompt (#) using: # # free && sync && echo 3 > /proc/sys/vm/drop_caches && free # First time for `du` 34 seconds. # Second time for `du` 1 second. # PARM: If any parm 1 passed use REAL kernel size, else use estimated size. # By default `du` is not used and estimated size is displayed. # Must be running as sudo if [[ $(id -u) != 0 ]]; then echo "root access required. Use: sudo rm-kernels-server" exit 99 fi # Must have the dialog package. On Servers, not installed by default command -v dialog >/dev/null 2>&1 || { echo >&2 "dialog package required but it is not installed. Aborting."; exit 99; } OLDIFS="$IFS" IFS="|" item_list=() # Deviate from rm-kernels here. current_version=$(uname -r) i=0 for f in /boot/vmlinuz* do if [[ $f == *"$current_version"* ]]; then continue; fi # skip current version [[ $f =~ vmlinuz-(.*) ]] ((i++)) # Item List v=${BASH_REMATCH[1]} # example: 4.9.21-040921-generic v_main="${v%-*}" # example: 4.9.21-040921 # Kernel size in /boot/*4.9.21-040921-generic* s=$(du -ch /boot/*-$v* | awk '/total/{print $1}') if [[ $# -ne 0 ]] ; then # Was a parameter passed? if [[ -d "/usr/src/linux-headers-"$v_main ]] ; then # Kernel headers size in /usr/src/*4.9.21-040921* s2=$(du -ch --max-depth=1 /usr/src/*-$v_main* | awk '/total/{print $1}') else s2="0M" # Linux Headers are not installed fi # Kernel image size in /lib/modules/4.9.21-040921-generic* s3=$(du -ch --max-depth=1 /lib/modules/$v* | awk '/total/{print $1}') else # Estimate sizof of optional headers at 125MB and size of image at 220MB if [[ -d "/usr/src/linux-headers-"$v_main ]] ; then s2="125M" else s2="0M" # Linux Headers are not installed fi s3="220M" fi # Strip out "M" provided by human readable option of du and add 3 sizes together s=$(( ${s//[^0-9]*} + ${s2//[^0-9]*} + ${s3//[^0-9]*} )) t=$(( t + s )) s=$s" MB" d=$(date --date $(stat -c %y $f) '+%b %d %Y') # Last modified date for display item_list=("${item_list[@]}" "$i" "$v ! $d ! $s" off) done cmd=(dialog --backtitle "rm-kernels-server - Total: $t MB excluding: $current_version" \ --title "Use space bar to toggle kernel(s) to remove" \ --column-separator "!" \ --separate-output \ --ascii-lines \ --checklist " Kernel Version --------- Modified Date Size" 20 60 15) selections=$("${cmd[@]}" "${item_list[@]}" 2>&1 >/dev/tty) IFS=$OLDIFS if [ $? -ne 0 ] ; then echo cancel selected exit 1 fi i=0 choices=() for select in $selections ; do ((i++)) j=$(( 1 + ($select - 1) * 3 )) choices[i]=$(echo ${item_list[j]} | cut -f1 -d"!") done i=0 list="" for choice in "${choices[@]}" ; do if [ "$i" -gt 0 ]; then list="$list- "; fi # append "-" from last loop ((i++)) short_choice=$(echo $choice | cut -f1-2 -d"-") header_count=$(find /usr/src/linux-headers-$short_choice* -maxdepth 0 -type d | wc -l) # If -lowlatency and -generic are purged at same time the _all header directory # remains on disk for specific version with no -generic or -lowlatency below. if [[ $header_count -lt 3 ]]; then # Remove all wxy-zzz headers list="$list""linux-image-$choice- linux-headers-$short_choice" else # Remove wxy-zzz-flavour header only, ie -generic or -lowlatency list="$list""linux-image-$choice- linux-headers-$choice" fi done if [ "$i" -gt 0 ] ; then apt-get purge $list fi 

NOTE: In the call to dialog the directive --ascii-lines is passed to replace line-draw extended character set (which ssh doesn’t like) with “+—–+” for drawing boxes. If you do not like this appearance you can use the --no-lines directive for no box at all.


July 28, 2017 Updates

The calculated size of each kernel was taken from /boot/*kernel_version* which were 5 files totaling ~50 MB. The formula has changed to include the files in /usr/src/*kernel_version* and /lib/modules/*kernel_version* . The calculated size for each kernel is now ~400 MB. The above code for rm-kernels and rm-kernels-server has been updated. However, the sample screens above do not reflect these changes yet.

The default is to estimate the size of files for linux-headers at 125 MB and linux-image at 220 MB because du can be painfully slow unless files are in cache. To get the real size using du pass any parameter to the script.

The total of all kernel sizes (excluding the current running version which cannot be removed) is now show in the title bar.

The dialog box used to display each Kernel’s Last Access Date . This date can get mass overwritten for all kernels during backup or similar operations. The dialog box now shows the Modified Date instead.

An easy way to get rid of almost all obsolete packages, packages no longer in any package list, along with obsolete kernels is to do one of the following:

 dpkg --purge $(aptitude search ?obsolete) 

However, this will miss packages that are still recommended by other packages, and the -R/–without-recommends argument does not resolve this problem.

dselect after switching sort mode with ‘o’ will show all obsolete packages including the ones aptitude misses, but some people don’t like using it.

The accepted answer using sed to remove older kernels permanently has some flaws, if someone has not rebooted the computer after upgrading kernel the command will remove the newer kernel too.

Here is an alternate solution that will consider all situations to remove actual older kernels only:

 #!/bin/bash kernels=( $(grep -Po "^linux-image-[^-]+-[^-]+-generic\b" < <(dpkg --get-selections)) ) cur_rel=$(grep -Po ".*(?=-[az]*$)" < <(uname -r)) for kernel in "${kernels[@]}"; do ker_rel=$(grep -Po "[0-9].*(?=-[az]*)" <<< "$kernel") dpkg --compare-versions "$ker_rel" gt "$cur_rel" && echo "Please Restart your computer first" && break dpkg --compare-versions "$ker_rel" lt "$cur_rel" && sudo apt-get remove "$kernel" done 

If you have any version that is newer than the current one this will give you a warning to restart you computer first. Also note that the older kernels are preserved due to a good reason which is if you somehow mess up your current kernel making your system unstable then you should be able to boot into any older kernel.

ailurus has the feature of removing old kernels as well as unused configurations. I personally remove it manually from synaptic. You can install ailurus from getdeb as well as ppa

You can use ukuu – it’s all GUI – to update and delete old Kernels. 适合我!

Just remember leave the last 2 installed and obviously the ‘running’ kernel.

You can also set ukuu to only show mainline releases, even RC kernels, hide point releases.

ukuu

You can find ukuu in Synaptic, or instructions are here:

OMG!Ubuntu ukuu install instructions

here is a rough outline of what I did, careful as I am no expert in linux, be sure you know what you are doing and have backed up any files you are modifying.

 gedit /boot/grub/grub.cfg 

then find the entries you want to keep, we will highlight and copy them

 cd /etc/grub.d ls 

you’ll see a list of files like 10_linux and 30_os-prober

 sudo chmod -x 10_linux 

this will stop form auto adding all the linux entries into the grub boot menu.

 gksudo gedit 40_custom 

open the custom boot menu file, then go back to grub.cfg (which should still be open in gedit), and copy the entries you want to keep… such as

 menuentry "My Default Karmic" { set root=(hd0,1) search --no-floppy --fs-uuid --set cb201140-52f8-4449-9a95-749b27b58ce8 linux /boot/vmlinuz-2.6.31-11-generic root=UUID=cb201140-52f8-4449-9a95-749b27b58ce8 ro quiet splash initrd /boot/initrd.img-2.6.31-11-generic } 

paste them into 40_custom , and then save it.

 sudo chmod 755 40_custom 

makes it executable, then finally we update grub which will change the grub.cfg file:

 sudo update-grub 

Now, BEWARE, if you update your kernel or OS, your boot menu probably will not update… you’ll have to do that manually. But doing this procedure will let you customize the boot menu a bit more, such as remove the kernel version and just put the ubuntu name… ie Ubuntu Lucid 10.04, etc…

Hope someone finds this helpful, as it took me a while to figure out… didn’t see this solution anywhere…

Install the synaptic package manager and go down to the filters tab (I think filters, if not try all 5) and select “local”. This will show you orphaned packages on your system, such as the kernels. After you uninstall them, run update-grub . That command updates the list of boot options for grub.

If this fails, you can always try apt-get remove linux-image-version-generic .

Based on a previous answer by David Kemp, the following script will purge all headers and images except for the last 2 versions.

 #!/bin/sh # This script assumes that the installed linux-image and linux-headers packages # share the same versions (ie if a linux-image version number is installed, # the corresponding linux-headers package will also be installed, and vice # versa.) SECONDTOLASTVER=$(dpkg --list | grep linux-image | awk '{ print $2 }' | sort -r -n | sed '/^[^0-9]\+$/d' | sed 's/^.*-\([0-9\.]\+-[0-9]\+\).*/\1/' | uniq | sed -n 2p) # get a list of package names matching the argument passed to the function, and # return only those package names which should be removed get_pkgs_to_remove_matching () { if [ -n "$SECONDTOLASTVER" ]; then echo $(dpkg --list | grep $1 | awk '{ print $2 }' | sort | sed -n '/'"$SECONDTOLASTVER"'/q;p') fi } echo $(get_pkgs_to_remove_matching linux-image) $(get_pkgs_to_remove_matching linux-headers) | xargs sudo apt-get -y purge 

The following string of commands will purge any installed linux kernels except the currently running one (grep -v uname -r ) and the lastest available kernel (dpkg -l | …. | tail -1):

 dpkg -l | grep -E linux-image-.*-generic | cut -d ' ' -f3 | grep -v `dpkg -l | grep -E linux-image-.*-generic | cut -d ' ' -f3 | tail -1` | grep -v `uname -r` | xargs apt-get -y purge 

I use this to keep desktop’s boot volumes relatively clean, but in a server situation you’d probably want to expand the logic and write some additional scripting to maintain a list of the last X kernels the server has booted.

Something like a startup script that does:

 uname -r >> /root/bootedkernels cat /root/bootedkernels | sort -u | tail -3 > /root/bootedkernels # Keep the last 3 booted kernels 

and then use:

 dpkg -l | grep -E linux-image-.*-generic | cut -d ' ' -f3 | grep -vf /root/bootedkernels | grep -v `dpkg -l | grep -E linux-image-.*-generic | cut -d ' ' -f3 | tail -1` | grep -v `uname -r` | xargs apt-get -y purge 

To have a bit more control over which versions to keep, explicitly select the ones you want to remove. For instance if you want to remove kernel versions 3.2.0.[49-53], use a simple for loop:

 for k in 49 51 52 53 ; do aptitude remove --purge linux-image-3.2.0-${k}-generic ; done 

Adjust the list of kernel versions to fit.

试试这个。 Run it as root.

Save this script as, say ./keep-n-kernels.sh

Pass, as a command line argument, the number of most recent kernels you want to preserve.

    
#!/bin/bash

# pass n as a command line argument, and it will find all the installed
# kernels and keep only the n most recent ones => uninstall all older ones

# dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'
# this command gives the list of all packages EXCEPT for the latest kernel.
# source : https://help.ubuntu.com/community/Lubuntu/Documentation/RemoveOldKernels

n=$1

# find the installed kernel versions :
# dpkg-query -W -f='${Version}\n' 'linux-image-*' | grep .  | sort -n
# gives version numbers, one in each line
# dpkg-query -W -f='${Version}\n' 'linux-image-*' | grep .  | sed 's/\...$//g' | grep -v '\...$'| sort -u
# gives only the ones that appear in linux-image

# suffix, eg -generic-pae
# the kind of kernel you boot into
suffix=$(uname -r | sed 's:^[0-9]\.[0-9]\.[0-9]\-[0-9]\{2\}::g')

command="apt-get purge "

for version in $(dpkg-query -W -f='${Version}\n' 'linux-image-*' | grep . | sed 's/\...$//g' | grep -v '\...$'| sort -u | head -n -${n})
做
    command=${command}"^linux-image-${version}${suffix} "
 DONE

$command

Sample usage :

# ./keep-n-kernels.sh 4 # launch the apt-get command to remove all but the 4 most recent kernels

If you want [AND AT YOUR OWN RISK], you can add a -y (or a force flag) to the apt-get command and make it non-interactive.

I’m using a KDE desktop, and the easiest option I found was using the kde-config-grub2 application as suggested here: https://www.kubuntuforums.net/showthread.php?58075-remove-old-linux-versions (which I already had installed for setting background image, default boot option, and the like). Next to the drop-down box where you can choose the default entry, there is a “Remove Old Entries” button. Clicking this button presents you with a list of all installed kernels and you can select which ones to remove. When you apply the changes it will use dpkg to actually remove them from the system as well as the GRUB menu.

Just to chime in, you can also issue

apt-get remove linux-{image,headers}-xyz-{1,2,...,n}

as root, and the job will be done.

I have a script for this that does not need very fancy string parsing.

Remove headers and images except the current one to release space

 sudo apt-get autoremove --purge 'linux-headers-[0-9].*' linux-headers-$(uname -r)+ linux-headers-$(uname -r | cut -d- -f1,2)+ 'linux-image-[0-9].*' linux-image-$(uname -r)+