Обновления ядра в Ubuntu с помощью Bash

    Часто бывает так, что поставив новую стабильную систему, да ещё и отмеченную как LTS, вам всё равно хочется установить новое ядро (в котором, например, улучшено энергосбережение и наконец-то заработает ваш новый планшет Genius).

    Патчить и собирать ядро из исходников — игра, конечно, интересная, но для ленивых пользователей Ubuntu существует готовый репозиторий. Одна беда — скачивать пакеты и следить за обновлениями придётся вручную.

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

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

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

    Итак, мы хотим получать новейшее ядро для своей версии Ubuntu из репозитория и устанавливать его в интерактивном или автоматическом (для работы с anachron) режимах.

    Ядра помеченные как rc (release candidate) устанавливать не будем, так как они часто ведут себя плохо, да и репозиторий не всегда содержат их полные версии.

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

    Таким образом придём к синтаксису
    sudo bash kernel_upd.sh [-a] [-u] [-h]
    

    где опции означают следующее:

    -a Включает автоустановку (скрипт не задаёт никаких дополнительных вопросов, что позволяет включить его как задание для anacron)

    -u Позволяет устанавливать ядра для версии Ubuntu отличной от нашей

    -h Короткая справка

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

    Стратегия

    • С помощью wget будем скачивать список доступных ядер.
    • С помощью grep и регулярного выражения будем отфильтровывать только те ядра, которые нам нужны (не являются rc и возможно соответствуют нашей версии Ubuntu).
    • Структура репозитория такова, что новые ядра размещаются в конце списка, поэтому дополнительная сортировка не требуется и последнее ядро будет самым новым. Получим его версию с помощью команды tail.
    • С помощью команды uname получим версию установленного в системе ядра.
    • Выделяем при помощи регулярных выражений мажорные версии установленного и доступного ядер, и в случае если доступна более новая версия — скачиваем её и устанавливаем с помощью команды dpkg.
    • Если получена ошибка — сообщаем о ней. Если всё прошло успешно — удаляем скачанные файлы и просим перезагрузиться.


    Полезные мелочи в Bash

    Используем в сообщениях имя скрипта $0

    Сообщения скрипта становятся намного более информативны если они показывают из какого скрипта они пришли. Параметр $0 содержит в себе имя выполняемого скрипта. Например, просьба запустить скрипт с правами суперпользователя может выглядеть так
    if [ `whoami` != 'root' ]; then
      echo "Permission denied. Run $0 as the root"
      exit 1;
    fi
    


    Получаем имя установленной версии Ubuntu

    В скриптах для Ubuntu очень полезно знать какая версия этого дистрибутива у нас установлена. Команда lsb_release помогает получить эту информацию
    RELEASE_CDN=`lsb_release -sc`
    


    Использование дополнительных команд

    Если мы хотим опционально использовать команды, которые возможно установлены в системе (например, оповещать пользователя с помощью send-notify если он доступен или kdialog если нет) то можно использовать следующий пример.

    Получаем пути для нужных команд с помощью which
    KNOTIFY=`which kdialog`
    NOTIFY=`which notify-send`
    

    Если полученный путь не пустой — то команда доступна
    if [[ -n $NOTIFY ]]; then
      notify-send 'Installation finished' "Kernel $KERNEL_A was succesfuly installed<br>
      Please, reboot your computer for the changes to take effect"
    elif [[ -n $KNOTIFY ]]; then
      kdialog --title 'Installation finished' --passivepopup "Kernel $KERNEL_A was succesfuly installed<br>
      Please, reboot your computer for the changes to take effect"
    fi
    


    Запрос подтверждения у пользователя

    Запуская скрипт в интерактивном режиме хорошим тоном будет попросить у пользователя подтверждения выполнения каких-либо действий. Для этого существует команда read которая вместе с if или case может стать мощным инструментом для общения с пользователем. Например,
    read -p 'Do you want to reboot computer now (y/n)?' REPLY
    if [ $REPLY == 'y' ]; then
      shutdown -r 0
    fi
    

    спросит у пользователя разрешения перезагрузить компьютер немедленно.

    Анализ опций скрипта

    Команда getopts предлагает мощное средство для анализа опций скрипта в каком бы виде они не были заданы -a -u или -au. Опции без параметров задаются с помощью двоеточия перед ними ":auh", опции с параметрами — с помощью двоеточия после них.
    while getopts ":auh" opt; do
      case "$opt" in
        "a") AUTO=1;;
        "u") RELEASE='';;
        "h")
          echo -e $USAGE
          exit 0;;
        "?")
          echo "Invalid option $OPTARG. Try $0 -h for help"
          exit 1;;
        *)
          echo "Unknown error while processing options"
          exit 1;;
      esac
    done
    


    Проверка статуса выполнения предыдущей команды $?

    Во время выполнения скрипта некоторые команды могут завершаться неудачно и рушить дальнейшее выполнение скрипта. Поэтому важно проверять статус выполнения таких команд. Этот статус содержится в параметре $?
    dpkg -i *.deb
    if [ $? -eq 0 ]; then
      echo "..."
    fi
    


    Перенаправление ввода вывода через |

    Не стоит забывать о полезной возможности перенаправить вывод одной команды на ввод другой с помощью оператора |
    KERNEL_A=`wget -qO - $REP | grep -o "v[0-9]\.[0-9].[0-9]*-"$RELEASE"\w*" | tail -n 1`
    

    Это позволяет совмещать базовые команды в одну, которая делает как раз то, что нам нужно (Команда выше получает последнюю стабильную версию ядра из репозитория и сохраняет её в переменной KERNEL_A).

    Использование пользовательских функций

    Пользовательские функции доступные в Bash позволяют значительно сократить объём кода скрипта.
    function clean {
      cd /
      echo 'Cleaning...'
      rm -rf /tmp/KERNEL_UPD
    }
    
    clean
    

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

    Заключение

    Что хочется сказать напоследок — конечно, Ubuntu — это Linux для людей, но это в первую очередь Linux, и приложив небольшие усилия вы получите не просто красивую оболочку для просмотра видео и сёрфинга в интернете, но и мощный конструктор, с помощью которого можно творить чудеса.

    И да прибудет с вами сила!

    P.S.: Спасибо пользователю egorinsk за полезное уточнение, которое может улучшить сложные скрипты.

    P.P.S.: Все те, кто с шипящим «не нужжжжно!» сливал мне карму, все те, кто сначала пишет комментарий, а потом думает, все те, кто знает единственный расово-верный способ как нужно жить ПРАВИЛЬНО — горите в аду! Чмоки =*
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 26
    • +2
      помню как впервые потратил пару часов на настройку параметров сборки ядра через menuconfig, нервно ждал, пока соберётся ядро, а когда с него удачно запустилась система — почти пустил слезу… романтика…
      • 0
        Да… когда-то это был настоящий квест, но дело того стоило. Помню как дрессировал пятую красную шапку (это которая теперь Fedora, а не которая Enterprice).

        Но потом, попробовав всего понемногу перешёл на Debian (а через пару лет появилась Kubuntu) и привык к удобству. Так что теперь за меня ядро собирают заботливые ребята из Canonical, а я им просто пользуюсь, сейчас это не критично и экономит время.
        • 0
          Да, вот времена то были, я 5-ю не стал, только 7-ю. Делал configure, make config, make и make install и шел пить кофе, а после правил конфиг grub-а. Сейчас же репозитории появились и менеджеры пакетов. Спасибо огромное за скрипт как и за саму статью с некоторыми полезными приемами написания bash скриптов.
          • 0
            Надеюсь где-нибудь пригодится =) А репозитории и раньше были, просто на диалапе с собранными из сырцов дровами для вин-модема особо не накачаешься.
        • +1
          Я не совсем понял, что оно должно делать. Почему wget, а не git (если мы хотим ядра, отличные от апстрима)?
          • 0
            Оно просто проверяет есть ли новое, собранное Canonical ядро и если есть — скачивает и устанавливает его. Посмотрите в репозиторий (ссылка в статье) там обычные deb пакеты.

            Ситуация из жизни — планшет Genius заработал только с ядром 3.4 (патчи только в него вошли и не факт, что бекпортируют в 3.3) поэтому иногда бывает полезно получить cutting edge с патчами Canonical.
          • 0
            В целом сам скрипт полезен как шаблон для скачивания чего угодно — flash, java SDK, javaFx, nvidia-drivers, deb пакетов которых нет в репозиории. Его можно добавить как задание в anacron и обновляться автоматически, так, как будто это пакеты из репозитория.
            • +1
              Вместо ручной проверки статуса выполненной команды (и ручного написания if после каждой строчки) стоит использовать либо set -e, либо trap ERR.

              Странно, что практически никто не использует эти команды. Мне кажется, это плохо, если произошла ошибка, а скрипт продолжает работать как ни в чем не бывало. так, например, получаются пустые бекапы: скрипт отработал, бекап есть, а данных в нем нет.
              • 0
                Тут не каждая строчка критична, поэтому можно обойтись и ручной проверкой, но ваш способ конечно более компактный.
              • +1
                Эмм.

                Зачем использовать линукс и репозитории, если вы всё равно качаете пакеты wget'ом? Для кого apt-get сделали?
                • +1
                  apt-get сделали для специально оформленных репозиториев, на произвольно оформленный список deb пакетов он не действует.
                  • 0
                    sudo add-apt-repository ppa:kernel-ppa/ppa
                    sudo apt-get update
                    sudo apt-get upgrade
                    • 0
                      промазал строкой — ответ ниже.
                • –2
                  в этом репозитории находится один пакет для oneric с ядром версии 3.0.0-12.20
                  • 0
                    А. ну да

                    «WARNING: all packages have been deleted from this repository»

                    Есть еще launchpad.net/~francisbrwn9/+archive/kernels, но в любом случае сабж это путь для какой-нибудь Slackware, но не для Ubuntu.

                    • –1
                      И там тоже ядро более старое и не известно с какими патчами. Но суть не в этом. Я думаю вы бы не стали ждать следующего выпуска Ubuntu чтоб у вас наконец-то заработал планшет. PPA — это конечно здорово можно создать свой и не мучаться, но с помощью скрипта вы используете готовые пакеты собранные Canonical!

                      Открою вам секрет, flashinstaller работает именно так — скачивает вам архив и распаковывает в нужную папку. Да и не всё есть в репозиториях, что-то лучше собирать самому, а что-то можно просто скачать с сайта производителя в виде deb пакета (тот же скайп например, хотя он пока обновлялся раз в столетие, но есть и другие примеры). Так что говорить, что это путь не Ubuntu — очень громко. К тому же именно так и поступают посетители сайта ubuntovod.ru где и были даны рекомендации по установке нового ядра. Так что же им теперь менять название сайта и дистрибутив?
                      • 0
                        >Я думаю вы бы не стали ждать следующего выпуска Ubuntu чтоб у вас наконец-то заработал планшет.

                        Не буду. Я напрягусь и найду репозиторий с ядром. И скайп у меня из репозитория, именно поэтому мне не нужна куча скриптов для обновления, хватает apt-get upgrade

                        >К тому же именно так и поступают посетители сайта ubuntovod.ru где и были даны рекомендации по установке нового ядра.

                        А вы инструкциям с заборов тоже следуете? На ***.ru вообще предлагают весь софт из .tar.gz ставить
                        • 0
                          Я за многие годы общения с линуксом следую своим инструкциям, а вас я ни к чему не принуждаю. Не нужно не пользуйтесь. Считаете напрягом поиск репозитория — хорошо.

                          Я написал скрипт для тех, кому это нужно, а такие люди есть. Я написал его так же потому, что мне было интересно вспомнить как это делается и возможно напомнить об этом ещё кому-то.
                          • –1
                            Нет, в своих скриптах вы превращаете Ubuntu в Slackware, или даже в windows. Это именно так не надо пользоваться своей системой, это нужно искоренять. Людей же нужно просвещать о существовании репозиториев и менеджера пакетов, а не поощрять их невежество.

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

                              Как же хорошо, что есть такие люди как вы, которые будут искоренять «невежество» и показывать как нужно жить!
                              • 0
                                Вот он способ монетизации! Ставьте Убунту, скачивайте мои скрипты и у вас есть 50% шанс получить Семёрочку Максимальную, ну или Слаку на крайняк =)
                                • +1
                                  dpkg -i *.deb
                                  неожиданно этот скрипт использует менеджер пакетов.

                                  PPA репозитории не совсем простая и удобная штука. Лучше делать свой.

                                  И зря вы на автора напали, это про скриптинг статья, а не про религию установки пакетов.
                      • 0
                        А ничего, что на эти ядра не наложены убунтовские патчи, что вызывает ряд проблем в т. ч. с работой upstart? Или если вместо лога загрузки стоит логотип дистра, то никаких проблем и нет, да?
                        • 0
                          На трёх машинах проблем нет. Откуда информация про патчи? По моему как раз эти ядра как раз не ванильные, а с патчами, хотя я это не утверждать не берусь. В любом случае административные задачи нужно выполнять понимая риск.

                          Это вообще статья скорее про скриптинг была.
                        • 0
                          У такого способа есть один недостаток — не работают проприетарные драйвера :( Поставил ядро свежее, но вместо системы — чёрный экран. Пришлось загружать штатое ядро.

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