Comment déterminer par programme le RPM du noyau de version le plus élevé installé?


9

Ce que je veux scénariser est quelque chose comme:

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

Le problème est que si la sortie de rpm -q kernelest quelque chose comme:

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

… Comment déterminer lequel est le plus élevé? Je sais qu'un simple tri de chaîne n'est pas fiable (il sera inversé avec cet exemple). Existe-t-il un raccourci avec rpm ou dois-je tout analyser et le comparer moi-même?


Vous pouvez utiliser /var/log/yum.log pour cela. Ou 'ls -lht / boot | grep vmlinuz 'si le noyau vous intéresse.
schaiba

Ce ne sont pas des méthodes fiables pour déterminer quelle est une version supérieure. La vérification / boot peut inclure des noyaux pour des partitions multiboot entièrement différentes.
sosiouxme

Peut-être que j'y réfléchis trop. rpm -q kernel semble toujours lister les noyaux dans l'ordre des versions. Est-ce fiable?
sosiouxme

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

1
Et sort -Vne donne pas un résultat correct?
Runium

Réponses:


14

TL; DR

La 3ème tentative fonctionne réellement! Je laisse les 2 premières tentatives afin que d'autres qui pourraient rencontrer ce Q & A à l'avenir puissent, espérons-le, avoir un aperçu de la façon dont un problème n'est pas trivial d'analyser les informations de version de RPM et de déterminer la lignée qui vient en premier, en second, etc.

Tentative n ° 1 (OP a dit que cela ne fonctionnait pas)

Cette commande triera la sortie et vous la donnera dans l'ordre des versions:

$ 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

POURQUOI CELA N'A PAS FONCTIONNÉ: Une personne naïve penserait que vous pouvez utiliser une variante de la sortcommande pour effectuer cette tâche, mais il y a suffisamment de variabilité et d'incohérence dans le formatage des informations de version réelles pour un RPM donné, ce n'est tout simplement pas '' t à la hauteur de la tâche.

Tentative n ° 2 (OP a dit que cela ne fonctionnait pas)

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

POURQUOI IL N'A PAS FONCTIONNÉ: J'espérais fortement que cette approche produirait les résultats que le PO recherchait, mais le problème avec celui-ci, comme @Joel l'a souligné dans les commentaires, est que le --lastcommutateur renvoie simplement les résultats triés par la date d'installation des RPM.

Tentative # 3

Celui-ci fera certainement le travail. J'ai trouvé une suite d'outils appelés RPM Development Tools. Cette suite comprend 2 outils qui vous permettront de déterminer si une version d'un RPM est plus récente ou plus ancienne qu'une autre.

Si le RPM n'est pas déjà installé, vous pouvez le faire comme suit:

yum install rpmdevtools

Le premier outil utile est appelé rpmdev-vercmp. Cet outil peut comparer 2 noms de RPM et vous dire lequel est le plus récent. Par exemple:

$ 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

Après avoir trouvé cela, j'étais prêt à assembler un script shell, mais j'ai réalisé que je suis paresseux, alors j'ai fouillé quelques minutes de plus et j'ai trouvé un autre outil dans la suite appelé rpmdev-sort.

Cet outil est de la saleté. Vous pouvez l'utiliser comme suit:

$ 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

Il y a beaucoup d'outils dans les outils de développement RPM qui pourraient valoir le coup d'œil pour d'autres, donc je les répertorie ici pour référence future.

$ 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

Une alternative au # 3

Une alternative que le PO mentionnée dans les commentaires est d'utiliser sort -V. Voilà une capitale -V. Je n'avais jamais entendu parler de cet interrupteur non plus. Depuis la sortpage de manuel:

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

En fait, il sortfournit une fonction pour trier les numéros de version afin que vous puissiez également effectuer le tri comme suit:

$ 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

Désolé, je ne pense pas. Un simple tri de chaîne mettrait kernel-2.6.10 avant kernel-2.6.9. Cela doit fonctionner de manière générique, pas seulement pour l'exemple.
sosiouxme

-n ne vous aide qu'avec le premier numéro. Essayez de trier ceci: 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 Le tri est absolument le mauvais outil ici, ainsi que tout ce qui ne sait rien des schémas de libération de version.
sosiouxme

@slm --lasttrie par heure d'installation du package, ce ne sera pas nécessairement le dernier noyau (s'ils ont fait une installation rpm manuelle d'une version de noyau inférieure, par exemple).
Bratchley

1
sort -V échouera dans un contexte. Supposons que vous vouliez comparer 2 versions d'un package - 1.15-abc et 1.15-2ab. La commande sort dirait que 1.15-abc est supérieur à 1.15-2ab. Mais en fait, pour rpm, 2ab est supérieur à abc.
crisron

1
sort -V très différent de rpmdev-sort. Je n'utiliserais pas ça avec rpms du tout. C'est bon pour un coup d'œil rapide, mais c'est tout.
Tommi Kyntola

1

Vous avez vraiment besoin d'utiliser la bibliothèque RPM pour obtenir un bon résultat. L'algorithme de comparaison de versions est ... décidément complexe. Il n'est pas trivial de réimplémenter dans le shell, mais si vous pouvez utiliser Python pour faire la comparaison réelle, cela devient relativement simple. Voir /programming/3206319/how-do-i-compare-rpm-versions-in-python pour un exemple de la façon de procéder.


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

Je pense que le tri par buildtime est moins susceptible d'avoir un cas d'angle où il échoue, contrairement à installtime. Cependant, --last est plus net.


0

--lastne vous indiquera pas le numéro de version le plus élevé, mais il sera commandé par date d'installation. Vous pouvez donc voir la dernière version installée:

[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

La plupart du temps (à moins d'une installation manuelle du noyau), les deux devraient être les mêmes.

Pour le faire 100% correctement 100% du temps, vous devrez réduire le 2.6.*format des deux versions du noyau , puis le séparer à partir de la 2.6 (RHEL ne rebasera pas de manière drastique dans une seule version, RHEL5 sera toujours un noyau 2.6) et il suffit d'itérer sur chaque ligne de sortie rpm (éventuellement trié --lastpour les performances) et de comparer chaque position par rapport à la position analogue dans la version du noyau que vous avez obtenue uname -rsi l'un des nombres est plus grand dans la chaîne de la base de données rpm que la chaîne uname, quittez immédiatement avec ce message.

Pour vous aider, une question similaire est posée ici . Mais cette fonction suppose une notation décimale purement en pointillés, vous pouvez donc comparer la position du nombre avant le trait d'union (car il n'y en a qu'un), puis utiliser la fonction bash de cette personne pour tester si la version du correctif est plus élevée unameque dans la chaîne de base de données rpm.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.