纯Perl RPM版本检查器

我有一台机器位于无法访问互联网的安全环境中。 我有CentOS的一个基本负载与一些额外的RPMs。 这包括PERL的基本安装,没有额外的模块。 它也没有安装GCC,所以我不能手动安装新模块,也不能使用CPAN来安装它们。 因此,我需要一个纯粹的Perl解决scheme。

我被要求创build一个Perl脚本来validation机器是否安装了特定的RPM列表,并且它们是特定的版本或更新版本。

以下是我到目前为止:

#!/usr/bin/perl use strict; use warnings; # This is the list of RPMs to look for on the machine. my @RPMs = ("bwm-ng", "celt051", "device-mapper-multipath", "device-mapper-multipath-libs", "dhcp", "dhcp-common", "ebtables", "freeglut", "glusterfs-api", "glusterfs-libs", "gnutls-utils", "gpm", "hmaccalc", "iftop", "iperf", "ipsec-tools", "iptraf", "iscsi-initiator-utils", "libsysfs", "lm_sensors", "lm_sensors-libs", "log4cpp", "lrzsz", "lzop", "mcsctrans", "minicom", "nc", "netcf-libs", "net-snmp", "net-snmp-libs", "net-snmp-utils", "omping", "perl-AppConfig", "perl-Pod-POM", "perl-Template-Toolkit", "pimd", "python-lxml", "quagga", "radvd", "smcroute", "usbredir", "yajl"); # These are the RPM versions that they should be equal to or newer than. my @RPMVersions = ("bwm-ng-0.6-6.el6.2.x86_64", "celt051-0.5.1.3-0.el6.x86_64", "device-mapper-multipath-0.4.9-87.el6.x86_64", "device-mapper-multipath-libs-0.4.9-87.el6.x86_64", "dhcp-4.1.1-49.P1.el6.centos.x86_64", "dhcp-common-4.1.1-49.P1.el6.centos.x86_64", "ebtables-2.0.9-6.el6.x86_64", "freeglut-2.6.0-1.el6.x86_64", "glusterfs-api-3.4.0.57rhs-1.el6_5.x86_64", "glusterfs-libs-3.4.0.57rhs-1.el6_5.x86_64", "gnutls-utils-2.8.5-18.el6.x86_64", "gpm-1.20.6-12.el6.x86_64", "hmaccalc-0.9.12-2.el6.x86_64", "iftop-1.0-0.7.pre4.el6.x86_64", "iperf-2.0.5-11.el6.x86_64", "ipsec-tools-0.8.0-25.3.x86_64", "iptraf-3.0.1-14.el6.x86_64", "iscsi-initiator-utils-6.2.0.873-14.el6.x86_64", "libsysfs-2.1.0-7.el6.x86_64", "lm_sensors-3.1.1-17.el6.x86_64", "lm_sensors-libs-3.1.1-17.el6.x86_64", "log4cpp-1.0-13.el6_5.1.x86_64", "lrzsz-0.12.20-27.1.el6.x86_64", "lzop-1.02-0.9.rc1.el6.x86_64", "mcsctrans-0.3.1-4.el6.x86_64", "minicom-2.3-6.1.el6.x86_64", "nc-1.84-24.el6.x86_64", "netcf-libs-0.2.4-3.el6.x86_64", "net-snmp-5.5-54.el6.x86_64", "net-snmp-libs-5.5-54.el6.x86_64", "net-snmp-utils-5.5-54.el6.x86_64", "omping-0.0.4-1.el6.x86_64", "perl-AppConfig-1.66-6.el6.x86_64", "perl-Pod-POM-0.25-2.el6.x86_64", "perl-Template-Toolkit-2.22-5.el6.x86_64", "pimd-2.3.0-1.x86_64", "python-lxml-2.2.3-1.1.el6.x86_64", "quagga-0.99.23.1-2014082501.x86_64", "radvd-1.6-1.el6.x86_64", "smcroute-2.0.0-0.x86_64", "usbredir-0.5.1-2.el6.x86_64", "yajl-1.0.7-3.el6.x86_64"); my $RPMname; #This reprepsents an individual RPM name within the @RPMs array. foreach $RPMname (@RPMs){ # Loop through the @RPMs array and query the RPM database for each RPM. my $cmd = "rpm -qa | grep " . $RPMname; my @cmdResults = `$cmd`; if (! @cmdResults){ print "\tMissing RPM: " . $RPMname . "\n\n"; # If the RPM isn't installed; inform the user. } else { foreach(@cmdResults){ print "\t" . $_ . "\n"; # Print the version of the RPM that's currently installed. # Compare the RPM version that's installed with the corresponding version that should be installed # as listed in the @RPMVersions array. # write some magic here. <------ } } } exit(0); 

我发现似乎是一个可能的解决scheme,但我似乎无法弄清楚如何调整适合我的scheme的代码。

见这里: http : //www.perlmonks.org/bare/?node=240384

由于上面提到的限制,我不能使用RPM :: VersionSort或其他几个与RPM相关的模块。

任何帮助将非常感激。

谢谢!

一些提示

你不需要grep例如

 rpm -q radvd radvd-1.9.2-9.el7.x86_64 echo $? 0 

如果一个包缺less$? 是1

 rpm -q nc package nc is not installed echo $? 1 

您可以使用–queryformat获取已安装的rpm软件包的版本

 rpm -q radvd --queryformat "%{VERSION}\n" 1.9.2 

你可以用rpm来做更多的事情 – 看看rpm.org网站 。

你甚至可以在不使用perl的情况下离开,所以看看Dennis 在这里的答案。

虽然这不能回答我原来的问题,但我想提供一下我最终的结果。 我已经能够说服那些权力允许我安装RPM :: VersionSort Perl模块。 所以这不是一个纯粹的Perl解决scheme,因为我希望find。

以下是我现在使用的感兴趣的人:

 #!/usr/bin/perl use strict; use warnings; use RPM::VersionSort; my $cmd; my $cmdResults; my %installedRPMs; #This will hold a list of all the RPMs from the baseRPMs list that ARE currently installed on the machine. my @missingRPMs; #This will hold a list of all the RPMs from the baseRPMs list that ARE NOT installed on the system. my %baseRPMs; #This is the list of RPMs that should be installed on the system and their corresponding version numbers. %baseRPMs = ("bwm-ng" => "0.6-6.el6.2", "celt051" => "0.5.1.3-0.el6", "device-mapper-multipath" => "0.4.9-87.el6", "device-mapper-multipath-libs" => "0.4.9-87.el6", "dhcp" => "4.1.1-49.P1.el6.centos", "dhcp-common" => "4.1.1-49.P1.el6.centos", "ebtables" => "2.0.9-6.el6", "freeglut" => "2.6.0-1.el6", "glusterfs-api" => "3.4.0.57rhs-1.el6_5", "glusterfs-libs" => "3.4.0.57rhs-1.el6_5", "gnutls-utils" => "3.8.5-18.el6", "gpm" => "1.20.6-12.el6", "hmaccalc" => "0.9.12-2.el6", "iftop" => "1.0-0.7.pre4.el6", "iperf" => "2.0.5-11.el6", "ipsec-tools" => "0.8.0-25.3", "iptraf" => "3.0.1-14.el6", "iscsi-initiator-utils" => "6.2.0.873-14.el6", "libsysfs" => "2.1.0-7.el6", "lm_sensors" => "3.1.1-17.el6", "lm_sensors-libs" => "3.1.1-17.el6", "log4cpp" => "1.0-13.el6_5.1", "lrzsz" => "0.12.20-27.1.el6", "lzop" => "1.02-0.9.rc1.el6", "mcsctrans" => "0.3.1-4.el6", "minicom" => "2.3-6.1.el6", "nc" => "1.84-24.el6", "netcf-libs" => "0.2.4-3.el6", "net-snmp" => "5.5-54.el6", "net-snmp-libs" => "5.5-54.el6", "net-snmp-utils" => "5.5-54.el6", "omping" => "0.0.4-1.el6", "perl-AppConfig" => "1.66-6.el6", "perl-Pod-POM" => "0.25-2.el6", "perl-Template-Toolkit" => "2.22-5.el6", "pimd" => "2.3.0-1", "python-lxml" => "2.2.3-1.1.el6", "quagga" => "0.99.23.1-2014082501", "radvd" => "1.6-1.el6", "smcroute" => "2.0.0-0", "usbredir" => "0.5.1-2.el6", "yajl" => "1.0.7-3.el6", ); print "The following RPMs and version numbers will be checked against this system:\n"; foreach(keys %baseRPMs){ print "\t" . $_ . ": " . %baseRPMs($_) . "\n"; } print "Press any key to continue."; <STDIN>; #Loop through the %baseRPMs list and build both the %installedRPMs list as well as the @missingRPMs list. for my $pkg (keys %baseRPMs){ $cmd = "rpm -q " . $pkg . " --queryformat \"%{VERSION}-%{RELEASE}\""; $cmdResults = `$cmd`; if ($cmdResults =~ /not installed/) { push @missingRPMs, $pkg; } else { $installedRPMs{$pkg} = $cmdResults; } } #Loop through the %installedRPMs list and verify their version numbers against the %baseRPMs list. foreach (keys %installedRPMs){ if (exists $baseRPMs{$_}){ print "Expected: " . $_ . ": " . $baseRPMs{$_} . "\n"; print "Installed: " . $_ . ": " . $installedRPMs{$_} . "\n"; if (rpmvercmp($installedRPMs{$_}, $baseRPMs{$_}) < 0 ) { print "RESULT: !!FAIL!! " . $_ . " version is OLDER than the specified version in the Functional Test Plan.\n"; } else { print "RESULT: PASS. " . $_ . " version is equal to or newer than the specified version in the Functional Test Plan. \n"; } print "-----------------------------------------------------------------------------------------------------\n\n"; } } #Print the list of @missingRPMs. if (@missingRPMs){ print "The following RPMs are NOT installed as defined by the Functional Test Plan:\n"; foreach(@missingRPMs){ print "\t" . $_ . "\n"; } print "\n*Any missing RPMs indicates the system is NOT built as defined by the Functional Test Plan.*\n"; } print "\n"; exit(0) 

;