我如何比较python中的Rpm版本 [英] How do I compare Rpm versions in python

查看:70
本文介绍了我如何比较python中的Rpm版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找出如何比较 RPMS(当前已安装)和(在本地存储库中可用)的 2 个列表,并查看哪些 RPMS 已过时.我一直在修改正则表达式,但是 RPMS 有很多不同的命名标准,我无法找到一个好的列表来使用.我的驱动器上没有实际的 RPMS,所以我无法执行 rpm -qif.

I'm trying to find out how I can compare 2 lists of RPMS (Currently installed) and (Available in local repository) and see which RPMS are out of date. I've been tinkering with regex but there are so many different naming standards for RPMS that i can't get a good list to work with. I don't have the actual RPMS on my drive so i can't do rpm -qif.

pattern1 = re.compile(r'^([a-zA-Z0-9_\-\+]*)-([a-zA-Z0-9_\.]*)-([a-zA-Z0-9_\.]*)\.(.*)')
for rpm in listOfRpms:
     packageInfo = pattern1.search(rpm[0]).groups()
     print packageInfo

这适用于绝大多数但不是全部 (2300/2400)

This works for a vast majority but not all (2300 / 2400)

  yum-metadata-parser-1.1.2-2.el5
('yum-metadata-parser', '1.1.2', '2', 'el5') **What I need

但是这些都不起作用,除非我打破了以前工作过的其他一些..

But none these work for instance unless I break some others that worked before..

  • wvdial-1.54.0-3
  • xdelta-1.1.3-20
  • xdelta-1.1.3-20_2
  • xmlsec1-1.2.6-3
  • xmlsec1-1.2.6-3_2
  • ypbind-1.17.2-13
  • ypbind-1.17.2-8
  • ypserv-2.13-14
  • zip-2.3-27
  • zlib-1.2.3-3
  • zlib-1.2.3-3_2
  • zsh-4.2.6-1

推荐答案

在 RPM 的说法中,2.el5 是发布字段;2 和 el5 不是单独的字段.但是,如您的示例所示,release 中不需要 . .从末尾删除 \.(.*) 以一次性捕获释放字段.

In RPM parlance, 2.el5 is the release field; 2 and el5 are not separate fields. However, release need not have a . in it as your examples show. Drop the \.(.*) from the end to capture the release field in one shot.

所以现在你有了一个包名、版本和发行版.比较它们的最简单方法是使用 rpm 的 python 模块:

So now you have a package name, version, and release. The easiest way to compare them is to use rpm's python module:

import rpm
# t1 and t2 are tuples of (version, release)
def compare(t1, t2):
    v1, r1 = t1
    v2, r2 = t2
    return rpm.labelCompare(('1', v1, r1), ('1', v2, r2))

你问那个额外的 '1' 是什么?那是时代,它覆盖了其他版本比较注意事项.此外,它通常在文件名中不可用.在这里,出于本练习的目的,我们将其伪装为1",但这可能根本不准确.如果您仅通过文件名,这是您的逻辑将被关闭的两个原因之一.

What's that extra '1', you ask? That's epoch, and it overrides other version comparison considerations. Further, it's generally not available in the filename. Here, we're faking it to '1' for purposes of this exercise, but that may not be accurate at all. This is one of two reasons your logic is going to be off if you're going by file names alone.

您的逻辑可能与 rpm 不同的另一个原因是 Obsoletes 字段,它允许将包升级为具有完全不同名称的包.如果您接受这些限制,请继续.

The other reason that your logic may be different from rpm's is the Obsoletes field, which allows a package to be upgraded to a package with an entirely different name. If you're OK with these limitations, then proceed.

如果您手头没有 rpm python 库,以下是比较 rpm 4.4.2.3 的每个发行版、版本和纪元的逻辑:

If you don't have the rpm python library at hand, here's the logic for comparing each of release, version, and epoch as of rpm 4.4.2.3:

  • 在每个字符串中搜索由垃圾 [^a- 分隔的字母字段 [a-zA-Z]+ 和数字字段 [0-9]+zA-Z0-9]*.
  • 将每个字符串中的连续字段相互比较.
  • 字母部分按字典顺序进行比较,数字部分按数字进行比较.
  • 如果出现一个字段为数字而一个字段为字母的不匹配情况,则始终认为数字字段更大(更新).
  • 如果一个字符串用完字段,则始终认为另一个字符串更大(更新).
  • Search each string for alphabetic fields [a-zA-Z]+ and numeric fields [0-9]+ separated by junk [^a-zA-Z0-9]*.
  • Successive fields in each string are compared to each other.
  • Alphabetic sections are compared lexicographically, and the numeric sections are compared numerically.
  • In the case of a mismatch where one field is numeric and one is alphabetic, the numeric field is always considered greater (newer).
  • In the case where one string runs out of fields, the other is always considered greater (newer).

有关详细信息,请参阅 RPM 源中的 lib/rpmvercmp.c.

See lib/rpmvercmp.c in the RPM source for the gory details.

这篇关于我如何比较python中的Rpm版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆