Как выборочно произвести чистку старых ядер внезапно

Очень расчетные Вопросы и ответы, Как я удаляю старые версии ядра для чистки меню начальной загрузки? не обеспечивает простой способ выборочно произвести чистку более старых ядер, если дополнительные приложения не установлены т.е. Тонкая настройка Ubuntu.

Острота Bash для удаления только старых Вопросов и ответов ядер дает "чистке все старое" решение, но я хочу сохранить последнее ядро в каждом поколении. т.е. удалите 4.7.1, 4.7.2..., но сохраните 4.7.5.

Существует ли способ просмотреть список путем прокрутки всех установленных ядер и выбрать определенные для чистки? Это не должно позволять производить чистку от в настоящее время рабочего ядра.

7
задан 13 April 2017 в 05:24

1 ответ

Преимуществом этого ответа является собственный Bash Ubuntu, используется, не устанавливая сторонние приложения. Пользователи пользовательских ядер, которые не использовали apt или dpkg может изменить этот сценарий удара для удовлетворения их потребностям.

Zenity основывал решение

Zenity предоставляет графический интерфейс терминалу. Здесь это используется, чтобы обработать список ядер и выбрать отдельные:

rm-kernels 1.png

Диалоговый заголовок сообщает о количестве ядер, их общего размера и текущей загруженной версии ядра. Текущее ядро исключено из общих количеств заголовка и не появляется список ядра.

Измененная Дата обычно является датой, ядро было выпущено. В моей системе, что дата "затронута" каждый раз, ядро загружается с помощью сценария перезагрузки крона (Как Вы узнаете, когда определенная версия ядра была в последний раз загружена?).

Для каждого ядра его размер в /boot о каталоге сообщают. Затем общий размер ядра суммирован для этих трех каталогов; / начальная загрузка,/usr/src/kernel_version и/lib/modules/kernel_version.

Если никакой параметр не передается rm-kernels общий размер оценивается и выставочная Оценка "заголовка. Общее количество". Это экономит время, работая du команда, которая может занять 30 секунд к 90 минутам в зависимости от того, сколько ядер Вы имеете и есть ли у Вас SSD или жесткий диск. Если Вы передаете какой-либо параметр вообще затем du используется для получения размеров ядра, и заголовок показывает "Реальное Общее количество", поскольку демонстрационный экран выше иллюстрирует.

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] 

apt purge отчеты 1 784 МБ будут освобождены, но реальные общие 2 379 МБ. Я не знаю, почему это отличается.

Вместо того, чтобы производить чистку ядер по одному и update-grub будучи повторяющимся образом названным в трудоемком цикле, выборы очищены внезапно.

Код

Скопируйте этот код в названный файл rm-kernels в /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 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

Примечание: Необходимо использовать sudo полномочия сохранить файл с Вашим любимым редактором.

К исполнимому использованию make-файла:

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

Серверная версия

rm-kernels-server серверная версия для выборочного удаления ядер внезапно. Вместо GUI (графическое) диалоговое окно основанное на тексте диалоговое окно используется для выбора ядер для чистки.

  • Прежде, чем запустить скрипт необходимо установить диалоговое функциональное использование:

    sudo apt install dialog

Диалоговое окно находится в Настольной установке Ubuntu по умолчанию, но не в Сервере Ubuntu.

Демонстрационный экран

rm-kernels-server 1

rm-kernels-server код удара

#!/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 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
    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

    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
    item_list=("${item_list[@]}" "$i" "$v ! $d ! $s ! $c" off)
done

# Write Kernel version and array index to unsorted file
> ~/.rm-kernels-plain # Empty any existing file.
for (( i=1; i<${#item_list[@]}; i=i+3 )) ; do
    echo "${item_list[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=()
i=1
while read -r ndx; do 
    SortedArr+=($i "${item_list[$ndx]}" "off")
    (( i++ ))
done < ~/.rm-kernels-ndx

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

cmd=(dialog --backtitle "rm-kernels-server - $n Kernels, 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 /boot Size  Total" 20 70 15)

selections=$("${cmd[@]}" "${SortedArr[@]}" 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 ${SortedArr[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 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

Примечание: В вызове к dialog директива --ascii-lines передается замене, тянут строка расширенный набор символов (который ssh не любит) с "+-----+" для рисования полей. Если Вам не нравится это появление, можно использовать --no-lines директива ни для какого поля вообще. Если Вы не используете ssh можно удалить --ascii-lines и Ваш дисплей будет форматирован с символами ничьей строка:

rm-kernels-server line draw


28 июля 2017 обновления

Расчетный размер каждого ядра был взят от /boot/*kernel_version* которые были 5 файлами всего ~50 МБ. Формула изменилась для включения файлов в /usr/src/*kernel_version* и /lib/modules/*kernel_version*. Расчетный размер для каждого ядра - теперь ~400 МБ.

Значение по умолчанию должно оценить размер файлов для заголовков Linux на уровне 125 МБ и изображения Linux на уровне 220 МБ потому что du может быть крайне медленным, если файлы не находятся в кэшируемом в памяти. Получить реальное использование размера du передайте любой параметр сценарию.

Общее количество всех размеров ядра (исключая текущую рабочую версию, которая не может быть удалена) является теперь шоу в строке заголовка.

Диалоговое окно раньше отображало Последнюю Дату Доступа каждого Ядра. Эта дата могла перезаписать массу для всех ядер во время резервных или подобных операций. Диалоговое окно теперь показывает Измененную Дату вместо этого.


5 августа 2017 обновления

Список ядра теперь отсортирован по Версии Ядра, а не алфавитно-цифровым образом.

Дополнительный столбец был добавлен для /boot size. В графическом Zenity присваивают версию последним изменениям столбца между "Реальной Общей" и "Оценкой. Общее количество", (Предполагаемое) в зависимости от параметра 1 передаваемый или нет.

5
ответ дан 23 November 2019 в 06:43

Другие вопросы по тегам:

Похожие вопросы: