RPM版本号通常由三部分组成:Epoch:Version-Release
,其中:
rpm
模块(推荐)Python的rpm
模块提供了直接的版本比较功能:
import rpm
def compare_rpm_versions(ver1, ver2):
return rpm.labelCompare(ver1, ver2)
# 示例:比较两个版本
ver1 = ('0', '1.2.3', '1.el7') # (epoch, version, release)
ver2 = ('0', '1.2.4', '1.el7')
result = compare_rpm_versions(ver1, ver2)
if result < 0:
print(f"{'.'.join(ver1)} 小于 {'.'.join(ver2)}")
elif result > 0:
print(f"{'.'.join(ver1)} 大于 {'.'.join(ver2)}")
else:
print(f"{'.'.join(ver1)} 等于 {'.'.join(ver2)}")
distutils.version
模块如果没有rpm
模块,可以使用distutils.version
中的LooseVersion
:
from distutils.version import LooseVersion
def compare_loose_versions(ver1, ver2):
v1 = LooseVersion(ver1)
v2 = LooseVersion(ver2)
if v1 < v2:
return -1
elif v1 > v2:
return 1
else:
return 0
# 示例
print(compare_loose_versions("1.2.3-1.el7", "1.2.4-1.el7"))
如果需要更精细的控制,可以自己实现比较逻辑:
import re
def parse_rpm_version(version_str):
# 分割epoch:version-release
epoch = '0'
if ':' in version_str:
epoch, version_str = version_str.split(':', 1)
version = release = ''
if '-' in version_str:
version, release = version_str.rsplit('-', 1)
else:
version = version_str
return (epoch, version, release)
def compare_versions(ver1, ver2):
# 解析版本
e1, v1, r1 = parse_rpm_version(ver1)
e2, v2, r2 = parse_rpm_version(ver2)
# 比较epoch
if int(e1) > int(e2):
return 1
elif int(e1) < int(e2):
return -1
# 比较version
v_compare = compare_version_parts(v1, v2)
if v_compare != 0:
return v_compare
# 比较release
return compare_version_parts(r1, r2)
def compare_version_parts(part1, part2):
# 分割数字和非数字部分
def split_part(part):
return [s for s in re.split(r'([0-9]+)', part) if s]
p1 = split_part(part1)
p2 = split_part(part2)
for i in range(max(len(p1), len(p2))):
# 获取当前部分,如果不存在则为空
c1 = p1[i] if i < len(p1) else ''
c2 = p2[i] if i < len(p2) else ''
# 如果都是数字,比较数值
if c1.isdigit() and c2.isdigit():
num1 = int(c1)
num2 = int(c2)
if num1 > num2:
return 1
elif num1 < num2:
return -1
else:
# 比较字符串
if c1 > c2:
return 1
elif c1 < c2:
return -1
return 0
# 示例
print(compare_versions("1:2.3.4-5.el7", "2.3.4-6.el7")) # 1:... > 0:...
print(compare_versions("2.3.4-5.el7", "2.3.4-6.el7")) # 5 < 6
rpm
模块,因为它实现了官方的比较算法。rpm
模块,distutils.version.LooseVersion
是一个不错的替代方案,但可能不完全符合RPM的版本比较规则。