首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Perl结果重复编译问题

Perl结果重复编译问题
EN

Stack Overflow用户
提问于 2011-08-09 18:10:42
回答 1查看 135关注 0票数 0

下面是我目前遇到问题的代码块。

有一些背景,我正在写一个脚本,它将检查我们的网络配置,通过rancid备份,以获得一组默认/需要的配置,并将任何错误输出到电子邮件。

它的工作方式是读取一个文件(文件名存储为$configs),然后使用正则表达式检查配置行是否存在。

下面的代码块应该执行以下操作。

open文件句柄,然后在文件打开时,找到以下两段Regex接口GigabitEthernet1-9/0-48和!之间的任何行。

然后,它应该检查两个正则表达式之间的行是否存在

日志记录事件链接状态日志记录事件生成树状态生成树portfast生成树bpduguard启用

如果上面的任何一行不在两个regex d消除器之间,那么它应该将相应的错误消息推送到数组中进行处理,并最终在稍后发送电子邮件。

虽然下面的代码块似乎工作正常(sortof),但我最终得到了重复的条目,我确信这与while语句中的push语句有关。

通常我会做这样的事情

代码语言:javascript
复制
  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的新手……

代码语言:javascript
复制
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 -输入文件

代码语言:javascript
复制
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 -输入文件

代码语言:javascript
复制
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
!

预期输出

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-08-09 19:29:45

首先,始终在代码顶部使用strictwarnings杂注。

其次,始终使用open的三参数版本,而不是两参数版本,并使用词法文件句柄:

代码语言:javascript
复制
open my $fh, "<", "$fulldir/$configs"
    or die "could not open '$fulldir/$configs': $!";

第三,local不会像您认为的那样工作,使用my创建存在于当前作用域中的变量。

第四,您是真的希望匹配第二个字符类中的012348,还是希望匹配整数048?如果你想要后者,你需要说

代码语言:javascript
复制
if (/(interface GigabitEthernet[1-9]\/(?:[1-3]?[0-9]|4[0-8]))\b/ .. /!/) {

我可能会这样写你的代码:

代码语言:javascript
复制
#!/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";
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6994551

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档