我如何比较python中的Rpm版本

Ada*_*dam 11 python regex rpm

我试图找出如何比较2个RPMS列表(当前已安装)和(在本地存储库中可用)并查看哪个RPMS已过期.我一直在修补正则表达式,但RPMS有很多不同的命名标准,我无法获得一个好的列表.我的驱动器上没有实际的RPMS,所以我不能做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
Run Code Online (Sandbox Code Playgroud)

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

  yum-metadata-parser-1.1.2-2.el5
('yum-metadata-parser', '1.1.2', '2', 'el5') **What I need
Run Code Online (Sandbox Code Playgroud)

但是,除非我打破其他之前工作的其他人,否则这些都不起作用.

  • 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
  • 拉链2.3-27
  • zlib的-1.2.3-3
  • zlib的-1.2.3-3_2
  • zsh的-4.2.6-1

Owe*_* S. 15

在RPM用语中,2.el5是发布字段; 2和el5不是单独的字段.但是,释放不需要.像您的示例所示.\.(.*)从最后放下以一次捕获释放区域.

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

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))
Run Code Online (Sandbox Code Playgroud)

你有什么额外的问题'1'?这是时代,它超越了其他版本比较考虑因素.此外,它通常在文件名中不可用.在这里,我们将它伪装成'1'用于本练习,但这可能根本不准确.如果你单独使用文件名,这就是你的逻辑关闭的两个原因之一.

您的逻辑可能与其不同的另一个原因rpmObsoletes字段,它允许将包升级到具有完全不同名称的包.如果您对这些限制没问题,请继续.

如果你手头没有rpmpython库,这里是比较每个版本,版本和时代的逻辑rpm 4.4.2.3:

  • 在每个字符串中搜索由垃圾分隔的字母字段[a-zA-Z]+和数字字段.[0-9]+[^a-zA-Z0-9]*
  • 将每个字符串中的连续字段相互比较.
  • 按字典顺序比较按字母顺序排列的部分,并以数字方式比较数字部分.
  • 如果不匹配,其中一个字段是数字,一个是字母,则数字字段始终被视为更大(更新).
  • 在一个字符串用完字段的情况下,另一个字符串总是被认为更大(更新).

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