Как удалить старые версии ядра, чтобы очистить меню загрузки?

Каждый раз, когда я устанавливаю новое ядро ​​Linux, оно остается в grub_config, каждый раз делая меню загрузки длиннее.

Я знаю, что могу вручную искать установленные пакеты и удалять их.

Предоставляет ли Ubuntu более простой способ очистить их или не показывать в списке загрузки?

735
задан 22 January 2016 в 18:20

38 ответов

Вы можете установить ubuntu-tweak, а затем перейти к Приложениям -> Системный инструмент -> ubuntu tweak и

enter image description here щелкнуть мышью по чистоте пакетов и чистке ядер. Он не показывает используемое в данный момент ядро, поэтому вы всегда будете в безопасности.

15
ответ дан 22 January 2016 в 18:20

10. 04 GUI Method

Computer Janitor может очистить старые ядра и, как мне кажется, по умолчанию устанавливается в Ubuntu (но не в Kubuntu).

GRUB 1, если вы используете это, имеет опцию в /boot/grub/menu.lst, чтобы указать, сколько ядер он должен показывать максимум. GRUB 2, насколько я могу судить, нет.

26
ответ дан 22 January 2016 в 18:20

Это чистое решение из командной строки.

Сначала сгенерируйте список всех установленных версий ядра, кроме текущего:

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 для удаления пакетов.

Сначала пробный запуск (используя первый генератор в качестве примера):

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)))

Затем реальный запуск:

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)))

Если вы хотите автоматизировать процесс, то добавьте параметр --yes:

sudo apt-get --yes purge $(
  ...)
5
ответ дан 22 January 2016 в 18:20

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

Решение на основе Zenity

Zenity предоставляет терминалу удобный графический интерфейс для обработки списка и выбора элементов с помощью радио-кнопки :

rm-kernels 1

Как видно из заголовка, текущее ядро, с которым вы загрузились, не может быть удалено и не включено в список. Сообщаемый размер - это объем, который будет сохранен в каталоге / boot . Больше сохраняется на вашем диске, потому что двоичные файлы ядра также находятся в других областях. Примечание от 27 июля 2017 г .: Каталоги / usr / src / * kernel_version * и / lib / modules / * kernel_version * теперь также включены. 12237] Дата изменения обнаруживается с помощью команды stat . В моей системе эта дата "затрагивается" каждый раз, когда ядро ​​загружается с помощью этого ( Как узнать, когда в последний раз загружалась конкретная версия ядра? ) cron сценарий перезагрузки. Однако в вашей системе датой будет дата выпуска ядра, а не дата последней загрузки.

apt-get purge дает вам возможность прервать работу

У вас есть последняя возможность просмотреть все, что будут очищены и увидят общее дисковое пространство (несколько вводящее в заблуждение), которое будет восстановлено:

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] 

Код

Скопируйте этот код в исполняемый файл с именем 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 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 '<span foreground="blue" font="14">Check box next to kernel(s) to remove</span>' \
        --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 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 для создания файла, поэтому используйте:

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

Чтобы использовать исполняемый файл:

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

Версия сервера

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

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

    sudo apt install dialog

Диалог находится в стандартной установке Ubuntu Desktop, но не в Ubuntu Server.

Пример экрана

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 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

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


Обновления от 28 июля 2017 г.

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

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

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

Диалоговое окно, используемое для отображения даты последнего доступа каждого ядра. Эта дата может быть перезаписана массово для всех ядер во время резервного копирования или аналогичных операций. В диалоговом окне теперь отображается Дата изменения .

4
ответ дан 22 January 2016 в 18:20

Простой способ избавиться почти от всех устаревших пакетов, пакетов, которых больше нет ни в одном списке пакетов, а также устаревших ядер - это выполнить одно из следующих действий. :

dpkg --purge $(aptitude search ?obsolete)

Однако при этом будут пропущены пакеты, которые по-прежнему рекомендуются другими пакетами, и аргумент -R / - без-рекомендует эту проблему не решает.

dselect после переключения режима сортировки с помощью 'o' покажет все устаревшие пакеты, включая те, которые отсутствуют в aptitude, но некоторым людям это не нравится.

3
ответ дан 22 January 2016 в 18:20

Моя однострочная программа для удаления старых ядер (это также освобождает дисковое пространство)

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}' просто выводит второй столбец (который представляет собой пакет name)
  • sort -V упорядочивает элементы по номеру версии
  • sed -n '/' `uname -r` '/ q; p' печатает строки перед текущим ядром
  • ​​xargs sudo apt-get -y purge очищает найденные ядра

Отключение вызова sed :

  • -n сообщает sed , чтобы он был тихим
  • `uname -r` выводит текущий установленный выпуск ядра - мы включаем его в обратные кавычки, чтобы вывод был включен как часть команды (вы также можете увидеть это как $ (uname -r)
  • / something / q говорит «Стоп», когда вы сопоставляете «что-то» (в данном случае так что-то выводится из uname -r ) - / окружает регулярное выражение
  • p - это print
  • the ; - это команда 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
289
ответ дан 22 January 2016 в 18:20

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

uname -r 

НЕ УДАЛЯЙТЕ ЭТО ЯДРО!

Затем введите команду ниже, чтобы просмотреть / перечислить все установленные ядра в вашей системе.

dpkg --list 'linux-image-*'

Найдите все ядра, которые ниже вашего текущего ядро. Когда вы знаете, какое ядро ​​следует удалить, продолжайте ниже, чтобы удалить его. Выполните следующие команды, чтобы удалить выбранное ядро.

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

Наконец, выполните приведенные ниже команды, чтобы обновить grub2.

sudo update-grub2 

Перезагрузите систему.

395
ответ дан 22 January 2016 в 18:20

Как @jarno и @earcam упомянул в их комментариях к вопросу, Вы сначала хотите удостовериться, что все Ваши пакеты ядра Linux отмечены как автоустановленный:

sudo apt-mark auto '^linux-.*-4\.12\.0-12(-generic)? 

Затем нормальное apt-get autoremove команда должна работать.

sudo apt-get autoremove --purge

Read эти документы для получения дополнительной информации.

Затем нормальное apt-get autoremove команда должна работать.

sudo apt-get autoremove --purge

Read эти документы для получения дополнительной информации.

0
ответ дан 5 September 2019 в 10:04

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

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