Come determinare a livello di programmazione l'RPM del kernel con la versione più alta installata?


9

Quello che voglio scrivere è qualcosa sulla falsariga di:

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

Il problema è che se l'output di rpm -q kernelè qualcosa del tipo:

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

... come faccio a determinare quale è più alto? So che un semplice ordinamento di stringhe non è affidabile (sarà indietro con questo esempio). Esiste una scorciatoia con rpm o devo analizzare tutto e confrontarlo da solo?


Puoi usare /var/log/yum.log per questo. O 'ls -lht / boot | grep vmlinuz 'se il kernel è quello che ti interessa.
schaiba,

Questi non sono metodi affidabili per determinare quale sia una versione successiva. Il controllo / avvio potrebbe includere kernel che sono per partizioni multiboot completamente diverse.
sosiouxme,

Forse lo sto pensando troppo. Il kernel rpm -q sembra sempre elencare i kernel nell'ordine di versione. È affidabile?
sosiouxme,

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

1
E sort -Vnon dà il risultato corretto?
Runium,

Risposte:


14

TL; DR

Il terzo tentativo funziona davvero! Lascio i primi 2 tentativi in ​​modo che altri che potrebbero imbattersi in queste domande e risposte in futuro possano sperare di avere una visione di quanto sia un problema non banale analizzare le informazioni sulla versione di RPM e determinare il lignaggio che è venuto prima, secondo, eccetera.

Tentativo n. 1 (OP ha dichiarato di non funzionare)

Questo comando ordina l'output e li fornisce nell'ordine di versione:

$ 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

PERCHÉ NON FUNZIONA: una persona ingenua potrebbe pensare che è possibile utilizzare alcune varianti del sortcomando per eseguire questa attività, ma c'è abbastanza variabilità e incoerenza nella formattazione delle informazioni sulla versione effettiva per un determinato RPM che non è semplicemente t fino al compito.

Tentativo n. 2 (OP ha dichiarato di non funzionare)

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

PERCHÉ NON FUNZIONA: Avevo grandi speranze che questo approccio avrebbe prodotto i risultati che l'OP stava cercando, ma il problema con questo, come sottolineato da @Joel nei commenti, è che l' --lastinterruttore sta semplicemente restituendo i risultati ordinati per la data di installazione degli RPM.

Tentativo n. 3

Questo sicuramente farà il lavoro. Ho trovato una suite di strumenti chiamati RPM Development Tools. Ci sono 2 strumenti in questa suite che ti daranno la possibilità di determinare se una versione di un RPM è più recente o più vecchia di un'altra.

Se l'RPM non è già installato, puoi farlo come segue:

yum install rpmdevtools

Viene chiamato il primo strumento utile rpmdev-vercmp. Questo strumento può confrontare 2 nomi di RPM e dirti quale è più recente. Per esempio:

$ 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

Dopo averlo trovato, ero pronto a mettere insieme uno script di shell, ma poi ho capito, amico, sono pigro, quindi ho frugato ancora qualche minuto e ho trovato un altro strumento nella suite chiamato rpmdev-sort.

Questo strumento è sporco. Puoi usarlo come segue:

$ 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

Ci sono molti strumenti in Strumenti di sviluppo RPM che potrebbero valere la pena di cercarli, quindi li elenco qui per riferimento futuro.

$ 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

Un'alternativa al n. 3

Un'alternativa che il PO menzionato nei commenti è di usare sort -V. Questa è una capitale -V. Nemmeno io avevo mai sentito parlare di questo interruttore. Dalla sortpagina man:

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

A quanto pare sortfornisce una funzione per ordinare i numeri di versione in modo da poter eseguire anche l'ordinamento in questo modo:

$ 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

Scusa, non credo. Un semplice ordinamento di stringhe mettere kernel-2.6.10 prima di kernel-2.6.9. Questo deve funzionare in modo generico, non solo per l'esempio.
sosiouxme,

-n ti aiuta solo con il primo numero. Prova a ordinare questo: 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 L'ordinamento è assolutamente lo strumento sbagliato qui, così come qualsiasi altra cosa non sa nulla degli schemi di rilascio delle versioni.
sosiouxme,

@slm --lastordina in base al tempo di installazione del pacchetto, non sarà necessariamente l'ultimo kernel (se, ad esempio, hanno eseguito un'installazione manuale rpm di una versione del kernel inferiore).
Bratchley,

1
sort -V la cosa fallirà in un contesto. Supponi di voler confrontare 2 versioni di un pacchetto: 1.15-abc e 1.15-2ab. Il comando sort direbbe che 1.15-abc è maggiore di 1.15-2ab. Ma infatti, per rpm, 2ab è maggiore di abc.
crisron,

1
sort -V è molto diverso da rpmdev-sort. Non lo userei affatto con rpms. Va bene per una rapida occhiata, ma è tutto.
Tommi Kyntola,

1

È davvero necessario utilizzare la libreria RPM per ottenere un buon risultato. L'algoritmo di confronto delle versioni è ... decisamente complesso. Reimplementare in shell non è banale, ma se puoi usare Python per fare il confronto reale, diventa relativamente semplice. Vedi /programming/3206319/how-do-i-compare-rpm-versions-in-python per un esempio di come farlo.


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

Penso che l'ordinamento per buildtime abbia meno probabilità di avere un caso angolare in cui fallisce, a differenza di installtime. Tuttavia, --last è più ordinato.


0

--lastnon ti dirà il numero di versione più alto ma ordinerà per data di installazione. Quindi puoi vedere l'ultima versione installata:

[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

Il più delle volte (a meno che non abbiano eseguito l'installazione manuale del kernel) i due dovrebbero essere gli stessi.

Per ottenerlo al 100% giusto nel 100% delle volte, dovrai 2.6.*formattare le due versioni del kernel per formattarle, quindi dividerle a partire dal 2.6 (RHEL non cambierà drasticamente in una singola versione, RHEL5 sarà sempre un kernel 2.6) e itererà su ogni riga dell'output di rpm (possibilmente ordinato --lastper prestazioni) e confronta ogni posizione con la posizione analoga nella versione del kernel ottenuta uname -rse uno qualsiasi dei numeri è più grande nella stringa di rpm db rispetto alla stringa uname, esce immediatamente con quel messaggio.

Per aiutarti là fuori c'è una domanda simile fatta qui . Ma quella funzione presuppone una notazione decimale puramente punteggiata, quindi puoi confrontare la posizione numerica prima del trattino (poiché ce n'è solo una) quindi utilizzare la funzione bash di quella persona per verificare se la versione della patch è superiore unamerispetto alla stringa rpm db.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.