下面是我目前遇到问题的代码块。
有一些背景,我正在写一个脚本,它将检查我们的网络配置,通过rancid备份,以获得一组默认/需要的配置,并将任何错误输出到电子邮件。
它的工作方式是读取一个文件(文件名存储为$configs),然后使用正则表达式检查配置行是否存在。
下面的代码块应该执行以下操作。
open文件句柄,然后在文件打开时,找到以下两段Regex接口GigabitEthernet1-9/0-48和!之间的任何行。
然后,它应该检查两个正则表达式之间的行是否存在
日志记录事件链接状态日志记录事件生成树状态生成树portfast生成树bpduguard启用
如果上面的任何一行不在两个regex d消除器之间,那么它应该将相应的错误消息推送到数组中进行处理,并最终在稍后发送电子邮件。
虽然下面的代码块似乎工作正常(sortof),但我最终得到了重复的条目,我确信这与while语句中的push语句有关。
通常我会做这样的事情
while (<FH>){
if (/(interface GigabitEthernet[1-9]\/[0-48])/../!/){
$text = $1;
if ($_ !~ /logging event link-status/){
$loggingconfigured++
}
}
if ($loggingconfigured++ == 0) {
push (@PortChecksIOS, "$configs port $text does not have logging event link-status set<br>")
}但是我失去了使用$text的能力,因为它在while循环之外被取消设置。
下面是当前的代码块,欢迎提出任何建议。但是请放心,我是perl的新手……
sub processPortChecksIOS{
local ($fulldir, $configs, @PortChecksIOS) = @_;
open FH, "$fulldir/$configs" or die $!;
while (<FH>){
if (/(interface GigabitEthernet[1-9]\/[0-48])/../!/){
$text = $1;
if ($_ =~ /switchport mode access/ && $_ !~ /shutdown/){
if ($_ !~ /logging event link-status/){
push (@PortChecksIOS, "$configs port $text does not have logging event link-status set<br>")
}
if ($_ !~ /logging event spanning-tree status/) {
push (@PortChecksIOS, "$configs port $text does not have logging event spanning-tree status set<br>")
}
if ($_ !~ /spanning-tree portfast/){
push (@PortChecksIOS, "$configs port $text does not have spanning-tree portfast set<br>")
}
if ($_ !~ /spanning-tree bpduguard enable/){
push (@PortChecksIOS, "$configs port $text does not have spanning-tree bdpuguard enable set<br>")
}
}
}
}
return @PortChecksIOS;
}样例输入sw-a-x.x -输入文件
interface GigabitEthernet1/0/1
description ftp5
switchport access vlan 51
switchport mode access
load-interval 30
spanning-tree portfast
!
interface GigabitEthernet1/0/2
switchport access vlan 51
switchport mode access
load-interval 30
spanning-tree portfast
!sw-a-z.z -输入文件
interface GigabitEthernet1/0/1
description ftp5
switchport access vlan 51
switchport mode access
load-interval 30
spanning-tree portfast
logging event link-status
spanning-tree status
spanning-tree bpduguard enable
!
interface GigabitEthernet1/0/2
switchport access vlan 51
switchport mode access
load-interval 30
spanning-tree portfast
!预期输出
sw-a-x.x interface GigabitEthernet1/0/1 does not have logging event link-status set
sw-a-x.x interface GigabitEthernet1/0/1 does not have logging event spanning-tree status
sw-a-x.x interface GigabitEthernet1/0/1 does not have spanning-tree bdpuguard enable set
sw-a-x.x interface GigabitEthernet1/0/2 does not have logging event link-status set
sw-a-x.x interface GigabitEthernet1/0/2 does not have logging event spanning-tree status
sw-a-x.x interface GigabitEthernet1/0/2 does not have spanning-tree bdpuguard enable set
sw-a-z.z interface GigabitEthernet1/0/2 does not have logging event link-status set
sw-a-z.z interface GigabitEthernet1/0/2 does not have logging event spanning-tree status
sw-a-z.z interface GigabitEthernet1/0/2 does not have spanning-tree bdpuguard enable set发布于 2011-08-09 19:29:45
首先,始终在代码顶部使用strict和warnings杂注。
其次,始终使用open的三参数版本,而不是两参数版本,并使用词法文件句柄:
open my $fh, "<", "$fulldir/$configs"
or die "could not open '$fulldir/$configs': $!";第三,local不会像您认为的那样工作,使用my创建存在于当前作用域中的变量。
第四,您是真的希望匹配第二个字符类中的0、1、2、3、4或8,还是希望匹配整数0到48?如果你想要后者,你需要说
if (/(interface GigabitEthernet[1-9]\/(?:[1-3]?[0-9]|4[0-8]))\b/ .. /!/) {我可能会这样写你的代码:
#!/usr/bin/perl
use strict;
use warnings;
sub process_port_checks_ios {
my ($fulldir, $configs) = @_;
open my $fh, "<", "$fulldir/$configs"
or die "could not open '$fulldir/$configs': $!";
my $range = qr/(?:[1-3]?[0-9]|4[0-8])\b/;
local $/ = "\n!\n"; #records are separated by ! at the start of a line
my @messages;
while (<$fh>) {
#skip records that aren't interfaces
next unless
my ($interface) = m{(interface GigabitEthernet[1-9]/$range/$range)};
my $base = "$configs port $interface does not have";
unless (/^logging event link-status$/m) {
push @messages, "$base logging event link-status set";
}
unless (/^logging event spanning-tree status$/m) {
push @messages, "$base logging event spanning-tree status set";
}
unless (/^spanning-tree portfast$/m) {
push @messages, "$base spanning-tree portfast set";
}
unless (/^spanning-tree bpduguard enable$/m) {
push @messages, "$base spanning-tree bdpuguard enable set";
}
}
return @messages;
}
print map { "$_\n" } process_port_checks_ios ".", "data";https://stackoverflow.com/questions/6994551
复制相似问题