суббота, 6 ноября 2010 г.

Автоматическое удаление старых ядер в Ubuntu

Долгое время мучался тем что вручную удалял старые ядра в Ubuntu после очередного обновления. Естественно такое удаление весьма не удобно тем, что приходилось самостоятельно искать в списке установленных пакетов что именно надо удалить. Чуть позже поискав в интернете нашел множество советов (например тут и тут). В большинстве случаев эти советы сводятся к использованию двух строчек, первая из которых формирует список установленных ядер ОС

dpkg-query -l linux-image-* |grep ^ii |grep -v e-g

а вторая удаляет то ядро, которые вы укажите

sudo apt-get -y remove <Имя_пакета_со_старым_ядром>

В течении полугода пользовался этим методом, пока не увидел на ноутбуке сестры при загрузке ОС 10 пунктов меню GRUB со старыми ядрами. Это в свою очередь заставило написать скрипт, которые автоматизирует рутинные операции по удалению старого ядра.

Логика работы скрипта достаточно проста, но не очень оптимальна. Сначала формируем файл с информацией об установленных ядрах ОС (точнее о пакетах) и сохраняем во временный файл tmp.txt.

#список установленных ядер
dpkg-query -l linux-image-* |grep ^ii |grep -v e-g > tmp.txt

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

ii  linux-image-2.6.32-25-generic 2.6.32-25.45 Linux kernel image for version 2.6.32 on x86

Собственно нас интересует только второй столбец, т.к. это и есть названия пакетов, которые следует удалить. Очевидно что необходимо взять все строки, кроме последней и записать результат во временный файл tmp1.txt.

#Подсчитываем количество установленных
#ядер и уменьшаем на 1 (т.е. исключаем самое новое ядро)
let a=$(cat tmp.txt | wc -l)-1
#Формируем список ядер для удаления
head -n $a tmp.txt  > tmp1.txt

Затем следует извлечь из оставшихся строк названия пакетов и сохранить во временный файл tmp.txt.

#Извлекаем из списка только имена
#пакетов для ненужных ядер
gawk -F" " '{ print $2 }' tmp1.txt  >  tmp.txt

После этого следует просмотреть получившийся файл с именами пакетов и удалить их. Для этого можно реализовать функцию на вход которой подадим файл tmp.txt.

#Функция, которая читает построчно файл
#со списком пакетов на удаление и удаляет эти пакеты
remove_kernel()
{
while read line
do
echo "Удаляю ядро: "$line
sudo apt-get -y remove $line
done
} < tmp.txt

После того, как функция описана ее можно вызвать.

#Вызываем функцию удаления
remove_kernel

#Удаляем временные файлы
rm tmp.txt
rm tmp1.txt

Скрипт написан не очень оптимально, но уже в таком виде нормально работает. Далее его можно подключить к службе cron и заставить выполнятся автоматически.

Полный текст скрипта

#!/bin/bash
#список установленных ядер
dpkg-query -l linux-image-* |grep ^ii |grep -v e-g > tmp.txt
#Подсчитываем количество
#установленных ядре и уменьшаем на 1
let a=$(cat tmp.txt | wc -l)-1
#Формируем список ядер для удаления
head -n $a tmp.txt  > tmp1.txt
#Извлекаем из списка только имена
#пакетов для ненужных ядер
gawk -F" " '{ print $2 }' tmp1.txt  >  tmp.txt
#Функция, которая читает построчно файл
#со списком пакетов на удаление и удаляет эти пакеты
remove_kernel()
{
while read line
do
echo "Удаляю ядро: "$line
sudo apt-get -y remove $line
done
} < tmp.txt   #Вызываем функцию удаления
remove_kernel 
#Удаляем временные файлы rm tmp.txt rm tmp1.txt