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

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

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

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

40 ответов

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

Однако была одна проблема: после установки нового ядра этот процесс удалял бы пакет для работающего в данный момент ядра!

Это не сломает ОС полностью. На самом деле я редко замечал, что это произошло, пока мне не потребовалась горячая загрузка модуля (например, путем подключения USB-устройства), а затем модуль не мог быть найден.

В качестве решения этой проблемы я создал скрипт для создания виртуального пакета. currently-installed-kernel который эффективно закрепляет текущий пакет ядра до следующей загрузки.

Сценарий называется pin-current-kernel-with-package.sh, Вот последняя версия (вероятно) и первая версия (определенно).

Просто сохраните этот скрипт где-нибудь и добавьте его в свой процесс загрузки. Например, сохранить его в /root/bit/pin-current-kernel-with-package.sh а затем редактировать /etc/rc.local и добавьте следующую строку:

bash /root/bin/pin-current-kernel-with-package.sh

Теперь ваш работающий пакет ядра никогда не будет удален!

Следующая строка команд удалит все установленные ядра Linux, кроме запущенного в данный момент (grep -v uname -r) и самое последнее доступное ядро ​​(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

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

Что-то вроде сценария запуска, который делает:

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

а затем используйте:

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

Если вы используете ansible для управления машинами, эта книга может оказаться полезной.

---
 - hosts: all
   become: yes
   tasks:
    - name: "Run apt-get autoremove"
      apt: 
        name: linux-image-generic
        autoremove: yes
        state: present 
        update_cache: yes
        cache_valid_time: 3600

Скорее использовать apt, клиент для людей, чем apt-get очистить старые образы ядра:

$ sudo apt autoremove --purge
...
The following packages will be REMOVED:
  linux-headers-4.4.0-51* linux-headers-4.4.0-51-generic* linux-image-4.4.0-51-generic* linux-image-extra-4.4.0-51-generic*

я использую этоremove_kernelскрипт для удаления старых версий ядра:

      #!/usr/bin/env bash

if [ -z "${1}" ]; then
  echo 'Choose one of kernels as command line parameter:'
  ls -l /boot | grep initrd | grep '^-r' | awk -F'-' '{print$8"-"$9}'
  exit 1
else
  KRNL="${1}"
fi

echo 'These files will be deleted:'
echo '------'
dpkg --list | egrep -i "$KRNL" | awk '{print$2}'
echo '------'
echo "  Version to remove: ${KRNL}"
echo "  Current version: $(uname -r | awk -F'-' '{print$1"-"$2}')"
echo '------'
printf 'Do you want to proceed [enter y to continue]: '
read iamagree

if [ "${iamagree}x" == "yx" ]; then
  sudo apt-get -y --purge remove $(dpkg --list | egrep -i "$KRNL" | awk '{print$2}' | xargs)
else
  echo "cancelled"
fi

Использование:

      $ remove_kernel
Choose one of kernels as command line parameter:
5.19.0-35
5.19.0-38
      $ remove_kernel 5.19.0-35
These files will be deleted:
------
linux-headers-5.19.0-35-generic
linux-hwe-5.19-headers-5.19.0-35
linux-image-5.19.0-35-generic
linux-modules-5.19.0-35-generic
linux-modules-extra-5.19.0-35-generic
------
  Version to remove: 5.19.0-35
  Current version: 5.19.0-38
------
Do you want to proceed [enter y to continue]: y
...

Проверено с помощьюUbuntu 22.04.2 LTS

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

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

Тогда нормальный apt-get autoremove Команда должна работать.

sudo apt-get autoremove --purge

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

Как я это сделал:

Сначала получите ядро, которое вы используете uname -r

Перечислите ядра и запишите более раннее ядро ​​(версия 5.15.0-35 при запуске 5.15.0-36 — см. 35 и 36 в конце?) и еще одно: 5.14.0-46 ( последний из серии 5.14). Таким образом, вы хотите сохранить две версии, чтобы вернуться к ним в случае необходимости).

       dpkg --list | egrep -i 'linux-image|linux-headers'

Удалите ненужное ядро. Обратите внимание, что

       sudo apt-get --purge remove $(dpkg --list | egrep -i 'linux-image|linux-headers' | awk '/ii/{ print $2}' | grep -v `uname -r` | grep -v 5.15.0-35 | grep -v 5.14.0-46 )

следующее может быть не нужно, но это также освободило место для меня - даже если оно должно быть таким же, как набор команд до

       dpkg -S "linux-image" 
 sudo apt-get --purge remove $(dpkg -S "linux-image" | cut -f'1' -d':' | grep -v 5.11 | grep -v 5.15.0-35 | grep -v 5.14.0-46 )

В конце выполните:

       sudo apt autoremove

Я даю два более безопасных варианта методов в других ответах: один с использованием администратора синапсов, а другой с помощью терминала.

С этими вариантами вы удаляете только те пакеты, которые система идентифицирует как сменные. Нет риска, что вы удалите ядра Linux, которые используются в настоящее время - как это случилось со мной несколько недель назад;-(

Использование Synaptic Manager

Вместо поиска linux-image над всеми установленными пакетами выберите автоматически удаляемые пакеты (см. красный эллипс на рисунке ниже). Теперь из этого списка удалите нужный вам linux-образ.

Используя терминал

Точно так же, если вы удаляете ядра на терминале, покажите только автоматически удаляемые ядра, запустив

 sudo apt-get -s autoremove | grep linux-image

А затем удалите любое ядро linux-image-x.x.x-x-generic вы хотите удалить из указанного списка, запустив

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

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

sudo apt autoremove --purge

Чтобы узнать ваш текущий выпуск ядра, запустите uname -r а также ты можешь бежать uname --help читать больше обо всех командах uname

Вы также можете запустить df -h чтобы показать вам драйверы файловой системы, аналогично вы можете запустить df --help для большего.

Чтобы включить автоматическое удаление старых ядер: отредактируйте файл конфигурации с помощью gksu

gksudo gedit /etc/apt/apt.conf.d/50unattended-upgrades

Когда файл откроется, раскомментируйте следующую строку и измените значение на true:

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

Если вам нужно установить gksu, вы можете запустить sudo apt install gksu

Для очистки старых пакетов мы можем использовать sudo apt-get clean

Для получения дополнительной информации посетите http://ubuntuhandbook.org/index.php/2016/05/remove-old-kernels-ubuntu-16-04/

Вот скрипт, который я использую, чтобы сохранить 2 установленных пакета ядра (т.е. текущий и предыдущий). Он также удаляет файлы initrd-VERSION-generic.old-dkms, оставленные DKMS, которые могут заполнить небольшой загрузочный раздел.

Сценарий:

echo "**Removing -generic.old-dkms files from /boot**" && rm -f /boot/*-generic.old-dkms # if using DKMS it creates initrd-VERSION-generic.old-dkms in /boot and doesn't clean them up, meaning after a few kernel upgrades /boot can become full
OLDKERNEL=$(ls -tr /boot/vmlinuz-* | head -n -2 | cut -d- -f2- | awk '{print "linux-image-" $0}')
OLDHEADERS=$(ls -tr /boot/vmlinuz-* | head -n -2 | cut -d- -f2- | sed 's/-generic//g' | awk '{print "linux-headers-" $0}')
OLDHEADERS=${OLDHEADERS//-pae/} # remove -pae string as linux-header packages don't have it in their names
if [ -n "$OLDKERNEL" -o -n "$OLDHEADERS" ]; then
apt-get -q remove --purge $OLDKERNEL $OLDHEADERS
echo "**Finished removing old kernels**"
else
echo "**No old kernels found**"
fi
Другие вопросы по тегам