Как удалить старые версии ядра, чтобы очистить меню загрузки?
Каждый раз, когда я устанавливаю новое ядро 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