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

    После очередного обновения убунты, я понял что меня вконец замучал растущий список загрузки в grub (это особенно актуально, если альтернативная ОС остается где-то внизу списка). Удалять вручную — это как-то неправильно, поэтому я решил заморочиться об автоматическом способе.

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

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

    #!/bin/bash

    kernels=`dpkg-query -l linux-image-* | grep ^ii | grep -v e-g | head -n -1 | gawk -F" " '{ print $2 }'`

    for i in $kernels
    do
    echo "Removing kernel: "$i
    # sudo apt-get -y remove $i
    done


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

    Надеюсь, кому-нибудь пригодится.

    Убедительная просьба: перед первым запуском команды, запустите ее без хвоста "| xargs apt-get -y purge" и убедитесь, что вы получаете корректный список ядер на удаление.

    UPD: Хабраюзеры Messie и ValdikSS подсказали более корректный и однострочный вариант:

    dpkg -l linux-image-* | grep ii | grep -v [a-z]-generic | grep -v `uname -r` | awk '{ print $2 }' | xargs apt-get -y purge

    UPD2: Вариант из скрипта ubucleaner от Steve_32:

    dpkg -l | grep ii | awk '{print $2}' | grep -E 'linux-(image|headers|ubuntu-modules|restricted-modules)' | grep -vE 'linux-(image|headers|restricted-modules)-(generic|i386|server|common|rt|xen)' | grep -v $(uname -r|sed 's/-*[a-z]//g'|sed 's/-386//g') | xargs apt-get -y purge
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 90

      –52
      Все правильно, только в конец надо добавить:
      echo «test… test… test...» | perl -e '$??s:;s:s;;$?::s;;=]=>%-{
        –42
        ;) Не смог удержаться…
          +9
          В скрипте из статьи нет ни одной завуалированной комманды, и по нему совершенно точно можно понять что он как минимум безвреден обладая базовыми знаниями линукса.

          rm -rf / – это как минимум, не совсем корректно. Могли бы уже и сломать перловую часть, все равно визуально было бы понятно. Ну или взять что-то не настолько убойное, хотя бы :(){ :|:& };:, если так хотелось подшутить.
            –27
            Я с вами совершенно согласен, в части, что любой обладающий базовыми знаниями линукса определит безвредность скрипта.
            Потому не обладая этими самыми базовыми знаниями писать статью на хабре — глупо. Для этого есть раздел вопросов и ответов.

            Далее, учитывая параною топикстартера, я на 100% был уверен в безобидности шутки ;)
            Кроме того мой второй комментарий является спойлером, он насторожил бы и не параноика ;)
              +13
              Я написал пост не потому, что решил блеснуть тем, что в чем-то разобрался (мой вклад минимален, учитывая, что исходный «рецепт» написан не мой), а просто потому, что знаю, что данная проблема для многих актуальна, но редко кто заморачивается, чтобы ее решить. Видимо поэтому быстрых и легких решений сходу найти не удалось. Уверен, что мое потраченное время (и время хабраюзеров, давших альтернативные варианты в комментариях) пойдет на пользу хотя бы нескольким людям — а значит, пост написан не зря. В конце концов все мы здесь сидим именно для обмена знаниями.

              А ваш первый комментарий многим людям помог?
                –25
                Учитывая что мой первый комментарий является шуткой — возможно кто-то улыбнулся с нуба, с вас то-есть ;)
                Однако если посмотреть на мою карму, скорее получилось наоборот, он дал возможность почувствовать власть и поднять чсв достаточно большому числу людей, что наверное тоже не так уж и плохо, если относиться к этому философски. А как к этому будешь относиться после того как тебя слили? ;) Только так.
                Думаю я заблуждался, и возможно эта статья кому-то полезна, раз уж она на главной ;)
                Но я все еще уверен, что патч Бармина вы бы не применили ;)
                  +11
                  1) Вас никто не оскорблял. Если вы в чем-то одном гений, то это не значит что во всем остальном — тоже, однако это не дает повода другим людям называть вас «нубом» — это как минимум не этично. У меня нет острой необходимости изучать shell скрипт, поэтому я его и не знаю. Это не мешает мне более чем успешно использовать убунту в качестве основной системы и выполнять несложные команды для достижения целей.

                  2) Не я один читаю это пост. Ваш «патч Бармина» может запустить кто угодно. Даже несмотря на крайне маленький шанс такого события в it-сообществе, такая вероятность все равно есть. Кстати, статьи на хабре видны извне и без аккаунта в системе, значит ваша шутка могла пойти и дальше — об этом вы не подумали?

                  3) Карма — имхо, показатель не сколько знаний, сколько адекватности человека. Ваши знания могут быть очень высокими в данной области, но преподнесли вы их так, что другим это не понравилось. Можно было дать простой вариант команды или указать на ошибку, верно? О чсв, кажется, стоит задуматься вам самому.

                  4) Насчет паранойи — во-первых, исходный скрипт все же немного изменен. Во-вторых, я не уверен, что он работает в 100% случаев и не удалит текущее ядро в каком-то особенном случае. И, конечно, мог бы не комментировать строчку удаления, потому что в моем случае все сработало корректно, однако, оказалось, что у ValdikSS данный код удалил бы текущее ядро. Почему же вы не указали на эту потенциальную проблему?

                  5) Нужность поста — вопрос, конечно, спорный. Я бы не написал его, если б не знал, что проблема актуальна. Но не мне судить, и не вам — решает само сообщество.
                +8
                Я с вами совершенно согласен, в части, что любой обладающий базовыми знаниями линукса определит безвредность скрипта.

                По-моему, «знание Линукса» и «знание Perl» не совсем одно и то же.
                  –13
                  Вы писали о знаниях перл?
                  вы писали следующее:
                  «В скрипте из статьи нет ни одной завуалированной комманды, и по нему совершенно точно можно понять что он как минимум безвреден обладая базовыми знаниями линукса.»

                  По этому поводу я написал следующее:
                  «я с вами согласен… Потому не обладая этими самыми базовыми знаниями писать статью на хабре — глупо. Для этого есть раздел вопросов и ответов.»

                  Ведь автор не написал решение, а написал найденное решение у которого закомментирована ключевая строка и задал вопрос, а правильно ли я делаю дорогое хабрасоообщество.
                  А обладай он минимальными знаниями этот вопрос не возник бы.
                  А по делу, то он должен был задать этот вопрос в разделе «вопросы и ответы», он для того и предназначен.

                  А по поводу патча бармина и знаний перл я написал следующее
                  "… я на 100% был уверен в безобидности шутки"
          +6
          Можно просто в одну строчку
          dpkg-query -l linux-image-* | grep ^ii | grep -v e-g | head -n -1 | awk '{ print $2 }' | xargs sudo aptitude -y purge
            +2
            valdikss@valdesktop ~ $ dpkg-query -l linux-image-* | grep ^ii | grep -v e-g | head -n -1 | awk '{ print $2 }'
            linux-image-2.6.35-28-generic
            linux-image-2.6.38-ck1-val
            valdikss@valdesktop ~ $ uname -a
            Linux valdesktop 2.6.38-ck1-val #4 SMP PREEMPT Thu Mar 24 15:38:17 OMST 2011 i686 GNU/Linux
            valdikss@valdesktop ~ $

            Т.е. он удалит мое текущее ядро.
            dpkg -l linux-image-* | grep ii | grep -v e-g | grep -v `uname -a | awk '{print $3}'` | awk '{ print $2 }'
              0
              dpkg -l linux-{image,headers}-* | grep ii | grep -v generic | grep -v `uname -a | awk '{print $3}'` | awk '{ print $2 }'
              а это еще и headers удалит ненужные
                0
                dpkg -l linux-{image,headers}-* | grep ii | grep -v generic | grep -v `uname -r` | awk '{ print $2 }'
                еще короче
                  0
                  А заголовки от текущего ядра системе не нужны?
                    0
                    А они не удаляться. uname -r выдает 2.6.38-ck1-val, что отсеивает и linux-image-2.6.38-ck1-val, и linux-headers-2.6.38-ck1-val
                      +1
                      удалятся*
                        0
                        В чем я туплю?

                        leenq@leenq-laptop:~$ dpkg -l linux-{image,headers}-* | grep ii | grep -v generic | grep -v `uname -r` | awk '{ print $2 }'
                        linux-headers-2.6.35-22
                        linux-headers-2.6.35-23
                        linux-headers-2.6.35-24
                        linux-headers-2.6.35-25
                        linux-headers-2.6.35-27
                        linux-headers-2.6.35-28
                        leenq@leenq-laptop:~$ uname -r
                        2.6.35-28-generic
                          0
                          Хм. Раз у вас ядро -generic, то и хидеры должны быть 2.6.35-28-generic. Смотрю сейчас у себя на linux-headers-2.6.35-28 и linux-headers-2.6.35-28-generic — в не-generic хидеры от разных архитектур, но еще и хидеры некоторых драйверов, инклюды, а в -generic все для x86. Может быть, можно удалить не-generic, но не уверен. Вроде, -generic все дублирует.
                            0
                            не-generic в любом случае при компиляции не будет использоваться, если вы компилируете под -generic ядром.
                              0
                              Ага, понял, спасибо :) Выношу ваш вариант в конец поста как наиболее вероятный в качестве окончательного (с учетом того, что те, кто компилирует под другими ядрами сами разбираются в том, что делают).
                                0
                                Окончательный вариант будет такой:
                                dpkg -l linux-{image,headers}-* | grep ii | grep -v generic | grep -v `uname -r` | awk '{ print $2 }' | xargs apt-get -y purge
                                  0
                                  Мне она хедеры всё таки снесла подчистую, пришлось вручную ставить. Снесла из-за пакета linux-headers-server, похоже.

                                  Сейчас она хочет удалить вот такие пакеты:
                                  linux-headers-2.6.35-28
                                  linux-headers-server
                                  linux-image-server
                                    0
                                    Ох, тогда нужно и их отсеивать. Хотя странно. Удалил у себя только что linux-image-generic, linux-image, linux-headers-generic — хидеры для моего ядра не удалились. Это же метапакеты всё, они не должны удалять что-то.
                                    Вам нужно добавить grep -v server между grep -v generic | grep -v `uname -r`
                                    0
                                    Почему-то не работает, если не пишу два раза «sudo» (через «su» тоже никак; 10.04.2 x86-64).
                                    Соответственно у меня вот какой вопрос: правильна ли строчка
                                    sudo dpkg -l linux-{image,headers}-* | grep ii | grep -v generic | grep -v `uname -r` | awk '{ print $2 }' | xargs sudo apt-get -y purge
                                    Или нужно второе sudo прямо перед «xargs» влепливать?
                                      0
                                      dpkg -l linux-{image,headers}-* | grep ii | grep -v generic | grep -v `uname -r` | awk '{ print $2 }'
                                      что-нибудь пишет? Sudo нигде больше не нужно. Попробуйте еще не xargs sudo, а sudo xargs. Перед dpkg sudo не надо.
                                        0
                                        Ничего не пишет — появляется строка ввода.
                                        sudo xargs работает так же, как и xargs sudo — выводится «0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.» — поэтому и хотел поинтересоваться, как правильнее писать.
                                          0
                                          Если появляется строка ввода — где-то не закрыта какая-нибудь кавычка. Вы уверены, что скопировали правильно? У меня все работает.
                                            0
                                              0
                                              А, я о другом подумал. Тогда убирайте по одной команде с конца(вместе с |) и покажите, когда начнет что-нибудь писать.
                                                0
                                                  0
                                                  Так у вас только одно ядро и стоит. uname -r вам скажет «2.6.32-30-generic»
                                                    0
                                                    Так и есть. Но мой вопрос был про расстановку sudo.
                                                      0
                                                      Не имеет значения. Либо sudo xargs, либо xargs sudo, больше нигде не нужно.
                                                      0
                                                      Я еще и ошибку нашел.
                                                      Окончательный вариант: dpkg -l linux-{image,headers}-* | grep ii | grep -v [a-z]-generic | grep -v `uname -r` | awk '{ print $2 }'
                                                        0
                                                        Странно, у меня в linux-headers-2.6.35-28-generic зависимость на linux-headers-2.6.35-28. Отсюда сносятся все хидеры, а от них и драйвер нвидии.
                                                          0
                                                          Поправил, спасибо. Я смотрю у многих возникают проблемы с заголовками, может их все-таки стоит исключить из удаления?
                                                            0
                                                            Можно и исключить. Тогда так:
                                                            dpkg -l linux-image-* | grep ii | grep -v [a-z]-generic | grep -v `uname -r` | awk '{ print $2 }'
                                                              0
                                                              Но ведь старые заголовки то незачем оставлять. В общем, вот мой вариант (подсмотрел в скрипте ubucleaner):

                                                              dpkg -l | grep ii | awk '{print $2}' | grep -E 'linux-(image|headers|ubuntu-modules|restricted-modules)' | grep -vE 'linux-(image|headers|restricted-modules)-(generic|i386|server|common|rt|xen)' | grep -v $(uname -r|sed 's/-*[a-z]//g'|sed 's/-386//g') | xargs apt-get -y purge

                                                              Хоть и длинный, но работать должен у всех =)
                                                              • НЛО прилетело и опубликовало эту надпись здесь
                            • НЛО прилетело и опубликовало эту надпись здесь
                          0
                          Это ошибка в изначальном варианте скрипта, Messie просто показал как выполнить его в одну строку. Спасибо за корректировку!
                        +12
                        sudo aptitude purge ~ilinux-image-.*\(\!`uname -r`\)
                          0
                          Под убунту ваша суперстрочка удалит не только linux-image-x.y.z-generic, но и linux-image-generic, т.е. обновления ядра не будут ставиться. То же самое будет и под Debian.
                            +4
                            А вот так работает отлично: удаляет все пакеты linux-image-[цифра] кроме текущей версии
                            sudo aptitude purge ~ilinux-image-\[0-9\]\(\!`uname -r`\)
                              +1
                              Да, тут уж не убавишь и не прибавишь. Публикуйте на commandlinefu.
                                0
                                >>на commandlinefu
                                спасибо за этот замечательный ресурс
                                0
                                а зачем хидеры оставлять?

                                sudo aptitude purge ~ilinux-.*-\[0-9\]\(\!`uname -r | sed 's/-generic//'`\)
                            +2
                            >на случай если где-то допустил критическую ошибку
                            для этого есть два удобных трюка:
                            1. перед командой писать echo, тогда на экран выведется команда, которая бы запустилась. ее же можно прямо тут выделить и запустить.
                            2. Улучшенный вариант предыдущего трюка подходит для больших скриптов. В начале объявляем любую переменную ( dfg=echo ), и дальше перед всеми командами ставим эту переменную ( $dfg rm -rf ${DEFINETLY_NOT_ROT} ). В итоговом варианте просто делаем dfg= и все сразу работает.
                              +1
                              Я, может, лезу не в своё дело, но у меня убунта при очередном ежедневном обновлении просто взяла, спросила, и почистила список старых ядер. За что ей большое спасибо.
                              P.S. Natty 11.04 alpha.
                                –1
                                10.10 так точно не делает. Во всяком случае пока что. А оставляет все предыдущие ядра.
                                  +1
                                  А ещё она увеличила разрешение экрана на окне GRUB до родного для ноута, и фон поставила фиолетовый.
                                  Раньше самого раздражал список ядер. Сейчас всё чисто, причём ничего руками не удалял.
                                    0
                                    ты еще расскажи про тот замечательный анимированный глюк в консоли :)
                                0
                                мда…

                                Как-то не понял я критерия определения, которе ядро старое, а которое не старое. У меня он предлагает удалить все ядра.

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

                                Так что первый комментарий описывает этот рецепт довольно точно.
                                  0
                                  Первоначальный скрипт просто брал список ядер и вычитал из него одну строчку. Конечно, это несовсем верно, хотя в большинстве случаев сработает нормально. Потому я и закомментировал критическую строчку.

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

                                  Запускаете вы этот скрипт-команду в любом случае вручную и сознательно, т.к. он требует подтверждение прав (а если ваша система успешно заработала под новым ядром, то старые, в принципе, можно удалить?)
                                    0
                                    Можно. Просто я это делаю в процессе ковыряния в aptitude, когда чешется чего-то обновить/удалить.
                                  +2
                                  Не вижу особого смысла делать это автоматически, а вообще есть такая полезная программа ubuntu-tweak. Много чего умеет в том числе и очищать систему. Одним из пунктов является очистка старых ядер.
                                    +2
                                    Вот не знаю почему, но данная софтина у меня всегда ассоциировалась со всякими:
                                    • WindowsXP tweak
                                    • Registry cleaner
                                    • Fine tune your windows now
                                    • Boot 10 times faster
                                    • RAM cleaner
                                    • Enlarge...
                                      +5
                                      Очень зря. На самом деле достаточно удобная и простая софтина. По меньшей мере, с её помощью удобно добавлять PPA репозитарии на свежеустановленную систему. Ну всякие Skype, Kepass, Dropbox и т.д. и т.п.
                                        0
                                        Да их и так можно добавлять, без всяких дополнительных программ.
                                        И да, не только из консоли.
                                          +3
                                          Можно, но так их искать не надо. Все популярные собраны в одном месте и разбиты по категориям.
                                            0
                                            Ну это уже «на любителя». Мне самому как-то привычнее добавлять, чем доверять программе с подозрительным названием.
                                            Слово «tweak» в названии программы всегда меня настораживало :)
                                              +2
                                              Да я вас хорошо понимаю. Но именно эта программа в итоге прижилась для первоначальной настройки системы.
                                              Никого ни к чему не принуждаю просто поделился полезной (для некоторых) софтиной :)
                                          0
                                          > По меньшей мере, с её помощью удобно добавлять PPA репозитарии на свежеустановленную систему.

                                          Полистал список PPA в Ubuntu Tweak, нашёл удобный bittorrent-клиент Flush, о котором раньше не знал.
                                          Внешне понравился, буду пробовать. Спасибо.
                                      +1
                                      launchpad.net/computer-janitor поможет тебе удалить осиротевшие пакеты, плюс в 11.04 в основном меню только самое свежее ядро, остальные — в подменю
                                        –2
                                        Для любителей Перла:
                                        dpkg-query -l linux-{image,headers}-* | sudo apt-get -y purge $(perl -ne "split,print \$_[1],' ' if(/^ii/&&! /generic/&&! /\Q`uname -r`\E/)")
                                          0
                                          Вопрос немного «сбоку»… А как сразу после устанвки нового ядра запустить какой нибудь скриптик чтобы например пересобрался бинарный драйвер?
                                          +1
                                          я юзаю для этого синаптик менеджер, поиск по linux-image и удаляю старые.
                                            0
                                            тоже в синаптике удаляю, хотя приведенные варианты для командной строки взял себе на заметку.
                                            0
                                            Ubuntu-tweak.
                                            Не автоматически, зато когда приспичит.
                                            Все равно нужно burg-update мне делать, т.к. grub только поддоном для burga служит.
                                            Если автомат как-то криво сработает — можно остаться без ядра совсем. А это печально…
                                              0
                                              > Если автомат как-то криво сработает — можно остаться без ядра совсем. А это печально…
                                              Печально, но восстанавливаемо. У меня бывало такое. Грузился с LiveUSB, chroot'ился и устанавливал ядро заново.
                                                0
                                                Это стояло того?
                                                Может проще через гуи все-таки?
                                              0
                                              У меня под убунтой список ядер остался на месте, зато успешно убились дрова на видеокарту(nvidia).
                                              Не все йогурты одинаково полезны.
                                                0
                                                драйвера с офсайта качали, поди?
                                                  0
                                                  Я просто нажал кнопку с надписью «активировать драйвер» в настройках бубунты. Откуда оно после этого их качает, не отслеживал.
                                                    +1
                                                    А, это из репозиториев.
                                                    Но ничего, в следующий раз будете пытаться разобраться, что за команды копипастите в консоль.
                                                  0
                                                  Я не спец, но мне кажется просто достаточно переустановить дяро (синаптек или как там его, там поиск linux-image-generic правый клик на «Отметить для повторной установки»). У меня что-то было похожее когда я хотел повыёживатся и поставить какое-то более свежее ядро чем сама ставится типа 2.6.38)

                                                  Возможно можно из консольки, но я только недавно с виндовса :)
                                                  0
                                                  Я использую ubucleaner скрипт www.ubuntugeek.com/ubucleaner-simple-bash-script-to-keep-your-ubuntu-system-clean.html

                                                  Работает юез нареканий. Кроме удаления ядер удаляет также stale пакеты.
                                                    +2
                                                    Не хватило вам терпения, но Шатлворд думает об этом…
                                                    После очередного обновления версии убунты, в грубе должна появиться строчка Previous Linux versions
                                                    habreffect.ru/files/486/2ad654be0/IMAG0086.jpg
                                                      +1
                                                      Проблема же не только в том, что строчки со старым ядром занимают место в GRUB-меню.
                                                      Старые же ядра ещё и занимают место в /boot. И если под /boot на диске выделен отдельный маленький раздельчик, то он так скоро переполнится. А значит старые ядра не только нужно скрывать в меню, но и действительно удалять их с /boot раздела.
                                                      0
                                                      Не запускайте, если есть проприетарные дрова для радеона. Выносит.
                                                        0
                                                        driver "fglrx"
                                                        работает даже без загруженного ядерного модуля, но недоступно ускорение. Как именно выносит?
                                                          0
                                                          деинсталлирует пакеты fglrx & DKMS модули.
                                                        0
                                                        хотелось бы чтоб параллельно удалялись директории старых модулей в /lib/modules/
                                                          0
                                                          Да, бесит, когда я GRUB-е видишь огромное количество доступных ядер, но-таки не кажется ли вам, что стоить удалять все, кроме последних двух ядер, текущую и предыдущую. Ко мне не раз обращались обычные юзеры ( моя девушка, например) и я удалял смело все, кроме последней, но порой система работает с новым ядром не так хорошо, как ожидалось, например alsa подводит ( с alsa-ой проблем после апдейта не встречался, но были другие ошибки). Я все к тому, что как в Windows есть «Последняя удачная конфигурация», так и тут оставить путь к отступлению…
                                                            0
                                                            Мне — кажется, но, к сожалению, сделать такую выборку корректно еще сложнее :( Опять же большинству пользователей подойдет исходный вариант скрипта, где нужно «head -n -1» поправить на «head -n -2» — и это, по идее, сработает. Но во многих других отдельных ситуациях такой вариант будет неприятно фатален.
                                                              0
                                                              «неприятно фатален» крайне точно описывает результат :)
                                                            0
                                                            Спасибо за элегантное решение :)
                                                            Меня тоже одно время «беспокоил» растущий список загрузки в grub
                                                              0
                                                              В аську прислали коммент:

                                                              Конструкцию вида "… | grep ii |… | awk '{ print $2 }'" можно сократить до "… | awk /ii/'{print$2}'" и использовать стиль «apt-get -y purge `ИНСТРУКЦИЯ ВЫБОРКИ-РАЗБОРА`»

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

                                                              Самое читаемое