Как программно определить установленную RPM версию ядра?


9

То, что я хочу, чтобы сценарий это что-то вроде:

if [ uname -r is not == highest version of kernel RPM installed ]
then
  echo "You need to reboot to use the latest kernel"
fi

Проблема в том, что если результат rpm -q kernelвыглядит примерно так:

kernel-2.6.32-358.10.2.el6.x86_64
kernel-2.6.32-358.6.1.el6.x86_64

... как определить, что выше? Я знаю, что простая сортировка строк не является надежной (в этом примере она будет обратной). Есть ли ярлык с rpm или мне нужно все разобрать и сравнить самому?


Для этого вы можете использовать /var/log/yum.log. Или 'ls -lht / boot | grep vmlinuz 'если ядро ​​- это то, что вас интересует.
schaiba

Это не надежные методы для определения, какая версия выше. Проверка / boot может включать ядра, предназначенные для совершенно разных разделов мультизагрузки.
Sosiouxme

Может быть, я обдумываю это. Ядро rpm -q всегда выводит список ядер в порядке версий. Это надежно?
Sosiouxme

'ls -lht / boot | grep vmlinuz | grep el6 ':)
schaiba

1
И sort -Vне дает правильного результата?
Runium

Ответы:


14

TL; DR

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

Попытка № 1 (OP сказал, что не работает)

Эта команда отсортирует выходные данные и выдаст их в порядке версий:

$ rpm -q kernel --queryformat "%{VERSION} %{RELEASE}\n"|sort -n
2.6.18 238.12.1.el5
2.6.18 238.19.1.el5
2.6.18 274.12.1.el5
2.6.18 308.8.2.el5

ПОЧЕМУ ЭТО НЕ РАБОТАЕТ: Наивный человек может подумать, что вы можете использовать какой-либо вариант sortкоманды для выполнения этой задачи, но в форматировании фактической информации о версии для данного RPM достаточно вариативности и несоответствия, что это просто не так. Т до задачи.

Попытка № 2 (OP сказал, что не работает)

$ rpm -q --last kernel | head -n 1 | cut -d' ' -f1
kernel-2.6.35.14-106.fc14

ПОЧЕМУ ЭТО НЕ РАБОТАЕТ: я возлагал большие надежды на то, что этот подход даст результаты, которые ищет ОП, но проблема с этим, как указал @Joel в комментариях, заключается в том, что --lastпереключатель просто возвращает результаты, отсортированные по дата установки RPM.

Попытка № 3

Этот определенно сделает работу. Я нашел набор инструментов под названием RPM Development Tools. В этом наборе есть 2 инструмента, которые дадут вам возможность определить, является ли одна версия RPM более новой или более старой, чем другая.

Если RPM еще не установлен, вы можете сделать это следующим образом:

yum install rpmdevtools

Первый полезный инструмент называется rpmdev-vercmp. Этот инструмент может сравнить 2 имени RPM и сказать вам, какое из них более новое. Например:

$ rpmdev-vercmp kernel-2.6.35.14-100.fc14.x86_64 kernel-2.6.35.14-103.fc14.x86_64
0:kernel-2.6.35.14-103.fc14.x86_64 is newer

После того, как я нашел это, я был готов собрать сценарий оболочки, но потом понял, чувак, я ленивый, поэтому я потыкал еще несколько минут и нашел в комплекте другой инструмент под названием rpmdev-sort.

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

$ rpm -q kernel | rpmdev-sort 
kernel-2.6.35.14-100.fc14.x86_64
kernel-2.6.35.14-103.fc14.x86_64
kernel-2.6.35.14-106.fc14.x86_64

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

$ rpm -q --queryformat '[%{NAME} %{FILEMODES:perms} %{FILENAMES}\n]' rpmdevtools \
    | grep -E "^.* -..x..x..x " \
    | awk '{print $3}'          \
    | sed 's#/usr/bin/##'       \
    | paste - - -               \
    | column -t

annotate-output   checkbashisms    licensecheck
manpage-alert     rpmargs          rpmdev-bumpspec
rpmdev-checksig   rpmdev-cksum     rpmdev-diff
rpmdev-extract    rpmdev-md5       rpmdev-newinit
rpmdev-newspec    rpmdev-packager  rpmdev-rmdevelrpms
rpmdev-setuptree  rpmdev-sha1      rpmdev-sha224
rpmdev-sha256     rpmdev-sha384    rpmdev-sha512
rpmdev-sort       rpmdev-sum       rpmdev-vercmp
rpmdev-wipetree   rpmelfsym        rpmfile
rpminfo           rpmls            rpmpeek
rpmsodiff         rpmsoname        spectool

Альтернатива № 3

Альтернатива, которую ОП упоминает в комментариях, заключается в использовании sort -V. Это столица -V. Я никогда не слышал об этом переключателе либо. Со sortстраницы руководства :

-V, --version-sort
       natural sort of (version) numbers within text

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

$ rpm -q kernel | sort -V
kernel-2.6.35.14-100.fc14.x86_64
kernel-2.6.35.14-103.fc14.x86_64
kernel-2.6.35.14-106.fc14.x86_64

Извините, я так не думаю. Простая сортировка строк поместит kernel-2.6.10 перед kernel-2.6.9. Это должно работать в общем, а не только для примера.
Sosiouxme

-n только поможет вам с первым номером. Попробуйте отсортировать это: 2.6.18 238.12.1.el5 2.6.18 238.19.1.el5 2.6.18 274.12.1.el5 2.6.18 274.8.2.el5 сортировка здесь абсолютно неправильный инструмент, как и все остальное, что ничего не знает о схемах выпуска версий.
Sosiouxme

@slm --lastсортирует по времени установки пакета, это не обязательно будет самое последнее ядро ​​(например, если они выполнили ручную установку rpm более низкой версии ядра).
Братчли

1
Сортировать -V вещь не удастся в одном контексте. Скажем, вы хотите сравнить 2 версии пакета - 1.15-abc и 1.15-2ab. Команда sort сказала бы, что 1.15-abc выше, чем 1.15-2ab. Но на самом деле, для оборотов, 2ab выше, чем abc.
Крисон

1
sort -V сильно отличается от rpmdev-sort. Я бы не стал использовать это с rpms вообще. Это нормально для быстрого взгляда, но это все.
Томми Кинтола

1

Вам действительно нужно использовать библиотеку RPM, чтобы получить хороший результат. Алгоритм сравнения версий ... безусловно сложен. Переопределение в оболочке нетривиально, но если вы можете использовать Python для фактического сравнения, это становится относительно простым. См. Https://stackoverflow.com/questions/3206319/how-do-i-compare-rpm-versions-in-python для примера того, как это сделать.


1
rpm -q kernel --queryformat="%{buildtime}\t%{name}-%{version}-%{release}.%{arch}\n" | sort -nr | head -1 | cut -f2

Я думаю, что сортировка по времени сборки с меньшей вероятностью будет иметь место в случае неудачи, в отличие от времени установки. Тем не менее, --last аккуратнее.


0

--lastне сообщит вам наибольший номер версии, но упорядочит по дате установки. Итак, вы можете увидеть самую последнюю установленную версию:

[root@xms_apps ~]# rpm -qa kernel-xen --last
kernel-xen-2.6.18-348.1.1.el5                 Tue 29 Jan 2013 02:18:52 PM EST
kernel-xen-2.6.18-308.11.1.el5                Fri 20 Jul 2012 04:00:26 PM EDT
kernel-xen-2.6.18-308.8.2.el5                 Wed 20 Jun 2012 03:32:47 PM EDT

В большинстве случаев (если они не установили ядро ​​вручную) они должны быть одинаковыми.

Чтобы получить 100% правильность в 100% случаев, вам нужно будет 2.6.*отформатировать две версии ядра, а затем просто разбить их на части, начиная с версии 2.6 (RHEL не будет сильно перебазировать в одной версии, RHEL5 всегда будет ядром 2.6) и просто перебирает каждую строку выходных данных rpm (возможно, отсортированных по --lastпроизводительности) и сравнивает каждую позицию с аналогичной позицией в версии ядра, из которой вы получили, uname -rесли любое из чисел больше в строке базы данных rpm чем строка uname, немедленно завершите работу с этим сообщением.

Чтобы помочь вам, есть похожий вопрос, заданный здесь . Но эта функция предполагает использование десятичной записи с точками в точках, поэтому вы можете сравнить числовую позицию перед дефисом (поскольку она есть только одна), а затем использовать функцию bash этого человека, чтобы проверить, выше ли версия патча, unameчем в строке rpm db.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.