我有一台位于安全环境中的机器,无法访问互联网。我有一个 CentOS 基本负载和一些额外的 RPM。这包括 PERL 的基本安装,没有额外的模块。它也没有安装 GCC,所以我无法手动安装新模块,也无法使用 CPAN 安装它们。因此,我需要一个纯 Perl 解决方案。
我被要求创建一个 Perl 脚本,用于验证机器是否安装了特定列表的 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);
我找到了一个看似可能的解决方案,但我似乎无法弄清楚如何调整代码以适应我的情况。
看这里:http://www.perlmonks.org/bare/?node=240384
由于上面提到的限制,我无法使用 RPM::VersionSort 或其他几个 RPM 相关模块。
如能提供任何帮助我将非常感激。
谢谢!
答案1
一些提示
你不需要 grep 例如
rpm -q radvd
radvd-1.9.2-9.el7.x86_64
echo $?
0
如果包裹缺少$?是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 的回答这里。
答案2
虽然这不能回答我最初的问题,但我想提供我最终得到的结果。我已经说服了那些有权势的人允许我安装 RPM::VersionSort Perl 模块。所以这不是我希望找到的纯 Perl 解决方案。
以下是我现在正在使用的内容,供感兴趣的人参考:
#!/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)
;