如何一次有选择地清除旧内核

Win*_*nix 7 apt boot grub2 kernel

高度评价的问答 如何删除旧内核版本以清理启动菜单?除非安装了额外的应用程序,即Ubuntu-Tweak ,否则不会提供一种简单的方法来选择性地清除旧内核。

猛砸一个班轮只删除旧内核的Q&A提供了一个“清除一切旧”的解决方案,但我想保持过去的内核中每一代。即删除 4.7.1、4.7.2...但保留 4.7.5。

有没有办法滚动浏览所有已安装内核的列表并选择要清除的特定内核?它不应允许清除当前正在运行的内核。

Win*_*nix 5

这个答案的优点是使用本机 Ubuntu Bash,无需安装第三方应用程序。未使用aptdpkg可以更改此 bash 脚本以满足其需要的自定义内核用户。

基于 Zenity 的解决方案

Zenity 为终端提供了一个 GUI 界面。这里用于处理内核列表并选择单个内核:

rm-内核 1.png

对话框标题报告内核的数量、它们的总大小和当前启动的内核版本。当前内核不包括在标题的总数中,并且不会出现在内核列表中。

修改日期通常是内核的发布日期。在我的系统上,每次使用cron重新启动脚本启动内核时,都会 “触及”该日期(您如何知道上次启动特定内核版本的时间?)。

对于每个内核,它在/boot目录中的大小都会被报告。然后将三个目录的内核总大小相加;/boot, /usr/src/ kernel_version和 /lib/modules/ kernel_version

如果没有参数传递给rm-kernels估计的总大小并且标题显示“Est. Total”。这可以节省运行du命令的时间,这可能需要 30 秒到 90 分钟,具体取决于您拥有多少内核以及您拥有的是 SSD 还是 HDD。如果您完全传递任何参数,则du用于获取内核大小,并且标题显示“Real Total”,如上例屏幕所示。

apt-get purge 给你机会中止

您可以查看将被清除的所有内容,并可以apt purge选择继续或中止:

The following packages will be REMOVED:
  linux-headers-4.4.0-78* linux-headers-4.4.0-78-generic*
  linux-headers-4.4.8-040408* linux-headers-4.4.8-040408-generic*
  linux-headers-4.6.3-040603* linux-headers-4.6.3-040603-generic*
  linux-headers-4.8.12-040812* linux-headers-4.8.12-040812-generic*
  linux-headers-4.9.0-040900* linux-headers-4.9.0-040900-generic*
  linux-headers-4.9.9-040909* linux-headers-4.9.9-040909-generic*
  linux-image-4.4.0-78-generic* linux-image-4.4.8-040408-generic*
  linux-image-4.6.3-040603-generic* linux-image-4.8.12-040812-generic*
  linux-image-4.9.0-040900-generic* linux-image-4.9.9-040909-generic*
  linux-image-extra-4.4.0-78-generic*
0 upgraded, 0 newly installed, 19 to remove and 1 not upgraded.
After this operation, 1,794 MB disk space will be freed.
Do you want to continue? [Y/n] 
Run Code Online (Sandbox Code Playgroud)

apt purge报告 1,784 MB 将被释放,但实际总数为 2,379 MB。我不知道为什么它不一样。

不是一次清除一个内核并update-grub在耗时的循环中重复调用,而是一次清除所有选择。

编码

将此代码复制到名为rm-kernelsin的文件中/usr/local/bin

The following packages will be REMOVED:
  linux-headers-4.4.0-78* linux-headers-4.4.0-78-generic*
  linux-headers-4.4.8-040408* linux-headers-4.4.8-040408-generic*
  linux-headers-4.6.3-040603* linux-headers-4.6.3-040603-generic*
  linux-headers-4.8.12-040812* linux-headers-4.8.12-040812-generic*
  linux-headers-4.9.0-040900* linux-headers-4.9.0-040900-generic*
  linux-headers-4.9.9-040909* linux-headers-4.9.9-040909-generic*
  linux-image-4.4.0-78-generic* linux-image-4.4.8-040408-generic*
  linux-image-4.6.3-040603-generic* linux-image-4.8.12-040812-generic*
  linux-image-4.9.0-040900-generic* linux-image-4.9.9-040909-generic*
  linux-image-extra-4.4.0-78-generic*
0 upgraded, 0 newly installed, 19 to remove and 1 not upgraded.
After this operation, 1,794 MB disk space will be freed.
Do you want to continue? [Y/n] 
Run Code Online (Sandbox Code Playgroud)

注意:您需要使用sudopowers 使用您喜欢的编辑器保存文件。

要使文件可执行,请使用:

#!/bin/bash

# NAME: rm-kernels
# PATH: /usr/local/bin
# DESC: Provide zenity item list of kernels to remove

# DATE: Mar 10, 2017. Modified Aug 5, 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.
#       With a magnetic hard disk, and empty memory cache:
#       the first `du` command averages about 20 seconds per kernel.
#       the second `du` command averages about 2.5 seconds per kernel.

# 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

    n=$(( n + 1 ))              # increment number of kernels

    # 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
    c=$(( ${s//[^0-9]*} + ${s2//[^0-9]*} + ${s3//[^0-9]*} ))
    s=$(( ${s//[^0-9]*} )) # Strip out M to make " MB" below which looks nicer
    t=$(( t + c ))
    s=$s" MB"
    c=$c" MB"
    d=$(date --date $(stat -c %y $f) '+%b %d %Y') # Last modified date for display
    choices=("${choices[@]}" false "$v" "$d" "$s" "$c")
done

# Write Kernel version and array index to unsorted file
> ~/.rm-kernels-plain # Empty any existing file.
for (( i=1; i<${#choices[@]}; i=i+5 )) ; do
    echo "${choices[i]}|$i" >> ~/.rm-kernels-plain
done

# Sort kernels by version number
sort -V -k1 -t'|' ~/.rm-kernels-plain -o ~/.rm-kernels-sorted

# Strip out keys leaving Sorted Index Numbers
cut -f2 -d '|' ~/.rm-kernels-sorted > ~/.rm-kernels-ndx

# Create sorted array
SortedArr=()
while read -r ndx; do 
    end=$(( ndx + 4 ))
    for (( i=$(( ndx - 1 )); i<end; i++ )); do
        SortedArr+=("${choices[i]}")
    done
done < ~/.rm-kernels-ndx

rm ~/.rm-kernels-plain ~/.rm-kernels-sorted ~/.rm-kernels-ndx

if [[ $# -ne 0 ]] ; then    # Was a parameter passed?
    VariableHeading="Real Total"
else
    VariableHeading="Est. Total"
fi

# 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 - $n Kernels, Total: $t MB excluding: $current_version" \
        --list \
        --separator="$IFS" \
        --checklist --multiple \
        --text '<span foreground="blue" font="14">Check box next to kernel(s) to remove</span>' \
        --width=800 \
        --height=480 \
        --column "Select" \
        --column "Kernel Version Number" \
        --column "Modified Date" \
        --column "/boot Size" \
        --column "$VariableHeading" \
        "${SortedArr[@]}"`)
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 w.x.y-zzz headers
        list="$list""linux-image-$choice- linux-headers-$short_choice"
    else
        # Remove w.x.y-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
Run Code Online (Sandbox Code Playgroud)

服务器版本

rm-kernels-server是一次有选择地删除内核的服务器版本。使用基于文本的对话框来选择要清除的内核,而不是 GUI(图形)对话框。

  • 在运行脚本之前,您需要使用以下命令安装对话框功能

    sudo apt install dialog

对话框位于默认的 Ubuntu 桌面安装中,但不在 Ubuntu Server 中。

示例画面

rm-内核-服务器 1

rm-kernels-server bash 代码

sudo chmod +x /usr/local/bin/rm-kernels
Run Code Online (Sandbox Code Playgroud)

注意:在对dialog指令的调用中,--ascii-lines通过ssh“+-----+”替换绘制框的画线扩展字符集(不喜欢)。如果您不喜欢这种外观,您可以完全使用--no-linesno box 指令。如果您不使用,ssh您可以删除--ascii-lines,您的显示将使用画线字符进行格式化:

rm-kernels-server 画线


2017 年 7 月 28 日更新

每个内核的计算大小取自/boot/*kernel_version*5 个文件,总计约 50 MB。该公式已更改为包括文件/usr/src/*kernel_version*/lib/modules/*kernel_version*。每个内核的计算大小现在约为 400 MB。

默认情况下,估计 linux-headers 的文件大小为 125 MB,linux-image 为 220 MB,因为du除非文件缓存在内存中,否则速度会非常慢。使用du将任何参数传递给脚本来获取实际大小。

所有内核大小的总和(不包括无法删除的当前运行版本)现在显示在标题栏中。

用于显示每个内核的上次访问日期的对话框。在备份或类似操作期间,此日期可能会被所有内核大量覆盖。该对话框现在显示修改日期


2017 年 8 月 5 日更新

内核列表现在按内核版本而不是字母数字排序。

已为 增加了一个附加列/boot size。在图形 Zenity 版本中,最后一列在“Real Total”和“Est. Total”(估计)之间变化,具体取决于参数 1 是否被传递。


归档时间:

查看次数:

6475 次

最近记录:

8 年,1 月 前