¿Cómo determinar mediante programación la versión más alta del kernel RPM instalado?


9

Lo que quiero escribir es algo parecido a:

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

El problema es, si la salida de rpm -q kerneles algo como:

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

... ¿Cómo determino cuál es más alto? Sé que un tipo de cadena simple no es confiable (será al revés con este ejemplo). ¿Hay un acceso directo con rpm o tengo que analizar todo y compararlo yo mismo?


Puede usar /var/log/yum.log para eso. O 'ls -lht / boot | grep vmlinuz' si el núcleo es lo que le interesa.
schaiba

Esos no son métodos confiables para determinar cuál es una versión superior. La comprobación / arranque puede incluir núcleos que son para particiones de arranque múltiple completamente diferentes.
sosiouxme

Tal vez lo estoy pensando demasiado. rpm -q kernel siempre parece enumerar los núcleos en orden de versión. ¿Es eso confiable?
sosiouxme

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

1
¿Y sort -Vno da el resultado correcto?
Runium

Respuestas:


14

TL; DR

¡El tercer intento realmente funciona! Dejo los primeros 2 intentos para que otros que puedan encontrarse con estas preguntas y respuestas en el futuro tengan alguna idea de cuán no trivial es el problema de analizar la información de la versión RPM y determinar el linaje de los cuales vino primero, segundo, etc.

Intento n. ° 1 (OP dijo que no funcionó)

Este comando ordenará la salida y le dará orden de versión:

$ 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

POR QUÉ NO FUNCIONÓ: una persona ingenua pensaría que puede usar alguna variante del sortcomando para realizar esta tarea, pero hay suficiente variabilidad e inconsistencia en el formato de la información de la versión real para un RPM dado que simplemente no es t a la altura de la tarea.

Intento n. ° 2 (OP dijo que no funcionó)

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

POR QUÉ NO FUNCIONÓ: tenía grandes esperanzas de que este enfoque arrojaría los resultados que el OP estaba buscando, pero el problema con este, como señaló @Joel en los comentarios, es que el --lastcambio solo está devolviendo los resultados ordenados por la fecha en que se instalaron los RPM.

Intento n. ° 3

Este definitivamente hará el trabajo. Encontré un conjunto de herramientas llamadas Herramientas de desarrollo RPM. Hay 2 herramientas en esta suite que le permitirán determinar si una versión de un RPM es más nueva o más antigua que otra.

Si el RPM no está instalado, puede hacerlo de la siguiente manera:

yum install rpmdevtools

La primera herramienta que es útil se llama rpmdev-vercmp. Esta herramienta puede comparar 2 nombres de RPM y decirle cuál es más nuevo. Por ejemplo:

$ 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

Después de encontrar esto, estaba listo para armar un script de shell, pero luego me di cuenta, hombre, soy flojo, así que busqué unos minutos más y encontré otra herramienta en la suite llamada rpmdev-sort.

Esta herramienta es de pago. Puede usarlo de la siguiente manera:

$ 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

Hay muchas herramientas en las Herramientas de desarrollo de RPM que podrían valer la pena para otras, así que las enumero aquí para referencia futura.

$ 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

Una alternativa al # 3

Una alternativa que el OP mencionado en los comentarios es usar sort -V. Eso es una capital -V. Nunca había oído hablar de este cambio tampoco. Desde la sortpágina del manual:

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

Como resultado sort, proporciona una función para ordenar los números de versión para que también pueda realizar la clasificación de la siguiente manera:

$ 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

Lo siento, no lo creo. Un tipo de cadena simple colocaría kernel-2.6.10 antes de kernel-2.6.9. Esto tiene que funcionar genéricamente, no solo por el ejemplo.
sosiouxme

-n solo te ayuda con el primer número. Intente ordenar esto: 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 sort es absolutamente la herramienta incorrecta aquí, así como cualquier otra cosa que no sabe nada sobre los esquemas de lanzamiento de versiones.
sosiouxme

@slm --lastordena por tiempo de instalación del paquete, no necesariamente será el último kernel (si hicieron una instalación manual de rpm de una versión inferior del kernel, por ejemplo).
Bratchley

1
La cosa sort -V fallará en un contexto. Supongamos que desea comparar 2 versiones de un paquete: 1.15-abc y 1.15-2ab. El comando sort diría que 1.15-abc es mayor que 1.15-2ab. Pero de hecho, para rpm, 2ab es más alto que abc.
crisron

1
sort -V muy diferente de rpmdev-sort. No usaría eso con rpms en absoluto. Está bien para un vistazo rápido, pero eso es todo.
Tommi Kyntola

1

Realmente necesita usar la biblioteca RPM para obtener un buen resultado. El algoritmo de comparación de versiones es ... decididamente complejo. No es trivial volver a implementar en shell, pero si puede usar Python para hacer la comparación real, se vuelve relativamente sencillo. Consulte /programming/3206319/how-do-i-compare-rpm-versions-in-python para ver un ejemplo de cómo hacerlo.


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

Creo que es menos probable que ordenar por tiempo de compilación tenga un caso de esquina donde falla, a diferencia del tiempo de instalación. Sin embargo, el último es más ordenado.


0

--lastno le dirá el número de versión más alto, pero lo ordenará por fecha de instalación. Para que pueda ver la versión instalada más recientemente:

[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 mayoría de las veces (a menos que hicieran una instalación manual del núcleo) los dos deberían ser los mismos.

Para hacerlo 100% correcto el 100% del tiempo, tendrá que obtener las dos versiones del kernel para 2.6.*formatearlas y luego dividirlas comenzando después de la 2.6 (RHEL no rebasará drásticamente eso en una sola versión, RHEL5 siempre será un kernel 2.6) e simplemente itere sobre cada línea de salida de rpm (posiblemente ordenada por --lastrendimiento) y compare cada posición con la posición análoga en la versión del kernel que obtuvo uname -rsi alguno de los números es mayor en la cadena de rpm db que la cadena uname, salga inmediatamente con ese mensaje.

Para ayudarlo, hay una pregunta similar aquí . Pero esa función asume una notación decimal puramente punteada, por lo que puede comparar la posición del número antes del guión (ya que solo hay una) y luego usar la función bash de esa persona para probar si la versión del parche es más alta unameque en la cadena rpm db.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.