如何以编程方式确定安装的最高版本内核 RPM?

如何以编程方式确定安装的最高版本内核 RPM?

我想要编写的脚本是这样的:

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 有捷径吗?还是我必须自己解析所有内容并进行比较?

答案1

长话短说

第三次尝试确实有效!我将留下前两次尝试,以便将来可能遇到此问答的其他人希望能够深入了解解析 RPM 版本信息并确定第一、第二的沿袭是多么重要的问题, ETC。

尝试#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

答案2

您确实需要使用 RPM 库才能获得良好的结果。版本比较算法……绝对复杂。在 shell 中重新实现并不简单,但如果你可以使用 Python 进行实际比较,它就会变得相对简单。看https://stackoverflow.com/questions/3206319/how-do-i-compare-rpm-versions-in-python有关如何执行此操作的示例。

答案3

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

我认为按构建时间排序不太可能出现失败的极端情况,这与安装时间不同。然而,--last 更简洁。

答案4

--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 数据库字符串中的任何数字更大)比 uname 字符串,立即退出并显示该消息。

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

相关内容