使用Python比较RPM包

使用Python比较RPM包,python,csv,rpm,Python,Csv,Rpm,我试图将包含所需Linux软件包的csv文件与当前安装的软件包进行比较。比较应输出任何未安装的软件包或比当前安装的软件包更新的软件包 问题是,我无法循环浏览已安装软件包的列表并显示所有点击率,例如名称和版本相同的软件包,但不同的体系结构应该显示两次(例如compat libstdc++-33),但我只能使用下面的脚本获得第一次点击率 #!/usr/bin/python import rpm import csv import sys import os ''' Script to check

我试图将包含所需Linux软件包的csv文件与当前安装的软件包进行比较。比较应输出任何未安装的软件包或比当前安装的软件包更新的软件包

问题是,我无法循环浏览已安装软件包的列表并显示所有点击率,例如名称和版本相同的软件包,但不同的体系结构应该显示两次(例如compat libstdc++-33),但我只能使用下面的脚本获得第一次点击率

#!/usr/bin/python

import rpm
import csv
import sys
import os

'''
Script to check installed rpms against a csv file containing the package name and version similar to the list below:
atk,1.12.2
libart_lgpl,2.3
info,4.9
libsepol,1.15.2
libusb,0.1.12
libfontenc,1.4.2

'''

if len(sys.argv) !=2:
        print ''
        print 'Usage: ', sys.argv[0], '/path/to/csv_input_file'
        print ''
        sys.exit(1)

if not os.path.isfile(sys.argv[1]):
        print ''
        print sys.argv[1], 'not found!'
        print ''
        sys.exit(1)

else:
        input_csv = sys.argv[1]

pkgRequired = csv.reader(open(input_csv),delimiter=',')

pkgInstalledName = []
pkgInstalledVersion = []
pkgInstalledArch = []

ts = rpm.TransactionSet()
mi = ts.dbMatch()

for h in mi:
        pkgInstalledName.append((h['name']))
        pkgInstalledVersion.append((h['version']))
        pkgInstalledArch.append((h['arch']))

for row in pkgRequired:
        pkgRequiredName = row[0]
        pkgRequiredVersion = row[1]
        #pkgRequiredArch = row[2]

        if pkgRequiredName in pkgInstalledName:

                if pkgInstalledVersion[pkgInstalledName.index(pkgRequiredName)] >= pkgRequiredVersion:
                        pass
                else:
                        print '\nInstalled:  ',pkgInstalledName[pkgInstalledName.index(pkgRequiredName)], pkgInstalledVersion[pkgInstalledName.index(pkgRequiredName)], pkgInstalledArch[pkgInstalledName.index(pkgRequiredName)], ' \nRequired: ', ' ', pkgRequiredName,pkgRequiredVersion

假设您读取已安装软件包列表的方式没有问题(我不熟悉rpm模块),那么您唯一的问题就是使用index()函数。此函数返回具有指定值的项的第一个匹配项,但它不是您想要的

正确的实施(也更有效)是:

installedPackages = {} #create a hash table, mapping package names to LISTS of installed package versions and architectures
for h in mi: 
  l = installedPackages.get(h['name'], list()) #return either the existing list, or a new one if this is the first time that the name appears.
  l.append( (h['version'], h['arch']) )

...
if requiredPackageName in installedPackages:
  for ver, arch in installedPackages[requiredPackageName]: print ...

这就是我为了让它工作而做的。该脚本目前没有检查所需软件包的体系结构,但至少显示了已安装的arch。该脚本可以工作(据我所知),但可以改进,因为它是我在python上的第一个脚本:)


谢谢你的回复。我想我做错了什么,因为我现在没有得到任何输出。
    #!/usr/bin/python

import rpm
import csv
import sys
import os

'''
Script to check installed rpms against a csv file containing the package name and version similar to the list below:
atk,1.12.2
libart_lgpl,2.3
info,4.9
libsepol,1.15.2
libusb,0.1.12
libfontenc,1.4.2

'''

#silverbullet - 20120301

if len(sys.argv) !=2:
        print ''
        print 'Usage: ', sys.argv[0], '/path/to/csv_input_file'
        print ''
        sys.exit(1)

if not os.path.isfile(sys.argv[1]):
        print ''
        print sys.argv[1], 'not found!'
        print ''
        sys.exit(1)

else:
        input_csv = sys.argv[1]

pkgRequired = csv.reader(open(input_csv),delimiter=',')

pkgInstalledName = []
pkgInstalledVersion = []
pkgInstalledArch = []

ts = rpm.TransactionSet()
mi = ts.dbMatch()

for h in mi:
        pkgInstalledName.append((h['name']))
        pkgInstalledVersion.append((h['version']))
        pkgInstalledArch.append((h['arch']))

for row in pkgRequired:
        try:
                pkgRequiredName = row[0]
                pkgRequiredVersion = row[1]
                #pkgRequiredArch = row[2] - This is not implemented yet, ie, script will ignore architecture in csv input file
        except:
                print "Unexpected Error. Check if input is csv format with no blank lines. "#, sys.exc_info()[1]
                break
        else:
                for pos, pkg in enumerate(pkgInstalledName):
                        if pkg == pkgRequiredName:
                                if pkgInstalledVersion[pos] >= pkgRequiredVersion:
                                        pass
                                else:
                                        print '\nInstalled:', pkgInstalledName[pos], pkgInstalledVersion[pos], pkgInstalledArch[pos], '\nRequired: ', pkg, pkgRequiredVersion