如何以编程方式确定安装的最高版本的内核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可能包括用于完全不同的multiboot分区的内核。
sosiouxme

也许我想得太多了。rpm -q kernel似乎总是按版本顺序列出内核。那可靠吗?
sosiouxme

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

1
sort -V没有给出正确的结果?
13年

Answers:


14

TL; DR

第三次尝试实际上有效!我将离开前两次尝试,以便将来可能会遇到此问答的其他人希望对解析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

为什么不起作用:我非常希望这种方法能够产生OP所寻找的结果,但是@Joel在评论中指出的这种方法的问题在于,该--last开关仅返回了排序依据RPM的安装日期。

尝试#3

这个肯定会做的。我找到了一套称为RPM开发工具的工具。该套件中有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

找到这个之后,我就准备好编写一个shell脚本,但是后来意识到,我很懒,所以我花了几分钟时间,在套件中找到了另一个工具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的替代品

注释中提到的OP的替代方法是使用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)。
布拉奇利2013年

1
sort -V事物将在一种情况下失败。假设您想比较软件包的2个版本-1.15-abc和1.15-2ab。sort命令会说1.15-abc高于1.15-2ab。但实际上,对于rpm,2ab高于abc。
crisron

1
sort -V与rpmdev-sort有很大不同。我根本不会在rpm上使用它。可以快速浏览一下,仅此而已。
Tommi Kyntola


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 db的字符串中的任何数字都较大)进行比较而不是uname字符串,请立即退出并显示该消息。

为了帮助你在那里有一个类似的问题在这里问。但是该函数采用纯点分十进制表示法,因此您可以比较连字符前的数字位置(因为只有一个),然后使用该人的bash函数测试补丁版本是否高于unamerpm db字符串中的版本。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.