2012-02-21 7 views
0

必要なLinuxパッケージを含むcsvファイルと現在インストールされているパッケージを比較しようとしています。この比較では、インストールされていないパッケージ、または現在インストールされているパッケージより新しいパッケージが出力されます。Pythonを使用したRPMパッケージの比較

問題は、インストールされたパッケージのリストをループしてすべてのヒットを表示できないことです。たとえば、同じ名前とバージョンのパッケージが2回表示されるはずです(たとえばcompat-libstdC++ - 33 )、しかし、私は下のスクリプトで最初のヒットを得るだけです。その後、あなたの唯一の問題は、インデックス()関数を使用している、あなたがインストールされたパッケージのリストを(私はRPMモジュールに慣れていないよ)読んでいる方法には問題がないと仮定すると

#!/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 

答えて

0

。この関数は、指定された値を持つアイテムの最初の出現を返します。これはあなたが望むものではありません。 (もはるかに効率的である)

正しい実装は次のようになります。

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 ... 
+0

お返事ありがとうございます。私は何も間違ったことをしていると思います。 – silverbullet

0

これは、私はこの作業を取得するためにやってしまったものです。このスクリプトは現在、必要なパッケージのアーキテクチャをチェックしていませんが、少なくともインストールされているアーチを示しています。スクリプトは(私の知る限りでは)動作しますが、私の最初の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 
+0

あなた自身の答えを受け入れてください。 –

関連する問題