Como determinar programaticamente o RPM do kernel da versão mais alta instalado?

9

O que eu quero roteiro é algo nos moldes de:

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

O problema é que, se a saída de rpm -q kernel for algo como:

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

… como eu determino qual é maior? Eu sei que uma simples seqüência de caracteres não é confiável (será ao contrário com este exemplo). Existe um atalho com rpm ou eu tenho que analisar tudo e compará-lo sozinho?

    
por sosiouxme 21.05.2013 / 17:52

4 respostas

13

TL; DR

A terceira tentativa realmente funciona! Estou deixando as duas primeiras tentativas para que outros que possam se deparar com este Q & A no futuro, esperançosamente, tenham uma ideia de como é um problema não trivial analisar as informações da versão do RPM e determinar a linhagem que veio primeiro. segundo, etc.

Tentativa nº 1 (OP disse que não funcionou)

Esse comando classificará a saída e fornecerá a você na ordem de versão:

$ 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 QUE NÃO TRABALHOU: Uma pessoa ingênua pensaria que você pode usar uma variante do comando sort para executar essa tarefa, mas há variabilidade e inconsistência suficientes na formatação de as informações da versão atual de um determinado RPM que simplesmente não está à altura da tarefa.

Tentativa nº 2 (OP disse que não funcionou)

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

POR QUE NÃO TRABALHO: Eu tinha grandes esperanças de que essa abordagem renderia os resultados que o OP estava procurando, mas a questão com este como @Joel apontado nos comentários, é que a opção --last está meramente retornando os resultados classificados pela data em que os RPMs foram instalados.

Tentativa nº 3

Este definitivamente fará o trabalho. Eu encontrei um conjunto de ferramentas chamado RPM Development Tools. Existem 2 ferramentas neste conjunto que lhe darão a capacidade de determinar se uma versão de um RPM é mais nova ou mais antiga que outra.

Se o RPM ainda não estiver instalado, você pode fazer o seguinte:

yum install rpmdevtools

A primeira ferramenta útil é chamada rpmdev-vercmp . Esta ferramenta pode comparar 2 nomes de RPMs e dizer qual é o mais novo. Por exemplo:

$ 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

Depois de encontrar isso, eu estava pronto para montar um shell script, mas depois percebi, cara, eu sou preguiçoso, então eu coloquei mais alguns minutos e encontrei outra ferramenta na suíte chamada rpmdev-sort .

Esta ferramenta é sujeira de pagamento. Você pode usá-lo da seguinte maneira:

$ 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

Existem muitas ferramentas nas Ferramentas de desenvolvimento de RPM que podem valer a pena procurar outras pessoas, por isso estou listando-as aqui para referência 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

Uma alternativa para o # 3

Uma alternativa que o OP mencionado nos comentários é usar sort -V . Esse é um capital -V . Eu nunca tinha ouvido falar desse interruptor também. Na página sort man:

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

Acontece que sort fornece um recurso para classificar os números de versão para que você também possa executar a classificação da seguinte forma:

$ 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
    
por 21.05.2013 / 18:10
1

Você realmente precisa usar a biblioteca RPM para obter um bom resultado. O algoritmo de comparação de versões é ... decididamente complexo. Não é trivial reimplementar no shell, mas se você puder usar o Python para fazer a comparação real, ele se tornará relativamente simples. Consulte o link para ver como fazer isso.

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

Acho que classificar pelo buildtime é menos provável de ter um caso específico em que ele falha, ao contrário do tempo de instalação. No entanto, o último é mais puro.

    
por 10.10.2016 / 21:31
0

--last não informa o maior número de versão, mas será ordenado por data de instalação. Assim, você pode ver a versão instalada mais recentemente:

[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

Na maior parte do tempo (a menos que tenham feito uma instalação manual do kernel), os dois devem ser os mesmos.

Para acertar 100% 100% do tempo, você terá que baixar as duas versões do kernel para 2.6.* format e então desmembrá-las a partir do 2.6 (o RHEL não vai rebase isso drasticamente em uma única versão, o RHEL5 sempre será um kernel 2.6) e apenas iterará sobre cada linha de saída rpm (possivelmente classificada por --last para desempenho) e compara cada posição com a posição análoga na versão do kernel obtida de uname -r se algum dos números for maior na string do db do rpm do que a string uname, saia imediatamente com essa mensagem.

Para ajudá-lo, há uma pergunta semelhante aqui perguntada . Mas essa função assume a notação decimal puramente pontuada, portanto você pode comparar a posição do número antes do hífen (desde que há apenas um) e usar a função bash dessa pessoa para testar se a versão do patch é maior em uname do que na string db do rpm. / p>     

por 21.05.2013 / 21:37

Tags