开发者

Perl result dupilcation issue

开发者 https://www.devze.com 2023-03-26 17:39 出处:网络
Below is the code block that i am currently having issues with. some background, I am writing a script that will check our network configs, backed up via rancid, for a set of default/need configurati

Below is the code block that i am currently having issues with.

some background, I am writing a script that will check our network configs, backed up via rancid, for a set of default/need configuration, and outputting any errors to an email.

It works by reading in a file (file name stored as $configs), i then use regex expresions to check for the existence/non existence of a line of config.

The bellow code block should do the following.

OPen the file handle, then whilst the file is open, locate any lines between the following two pieces of Regex interface GigabitEthernet[1-9]/[0-48] and !

It should then check the lines between the two regex for the existence of the lines

logging event link-status logging event spanning-tree status spanning-tree portfast spanning-tree bpduguard enable

If any of the above lines are not between the two regex d eliminators, then it should push the corresponding error message into the array for processing and eventual emailing later.

Whilst the code block below seems to work (sortof) I end up with duplicate entries, which im sure has something to do with the push statements being inside the while statement..

Normally i would do something like this

  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>")
  }

But I lose the ability to use $text has it becomes unset outside the while loop.

Below is the code block as it currently stands, any suggestions are welcomed. But please go easy im new to this perl stuff....

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&开发者_如何学Golt;br>")
            }
            if ($_ !~ /spanning-tree bpduguard enable/){
                push (@PortChecksIOS, "$configs port $text does not have spanning-tree bdpuguard enable set<br>")
            }
            }
        }

   }

return @PortChecksIOS;
}

Sample input sw-a-x.x - input file

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 - input file

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
!

expected output

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


First, always use the strict and warnings pragmas at the top of your code.

Second, always use the three argument version of open, never the two argument version , and use lexical filehandles:

open my $fh, "<", "$fulldir/$configs"
    or die "could not open '$fulldir/$configs': $!";

Third, local does not do what you think it does, use my to create variables that exist in the current scope.

Fourth, do you really want to match 0, 1, 2, 3, 4, or 8 in that second character class, or do you want to match the integers 0 through 48? If you want the later, you need to say

if (/(interface GigabitEthernet[1-9]\/(?:[1-3]?[0-9]|4[0-8]))\b/ .. /!/) {

I would probably write your code like this:

#!/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";
0

精彩评论

暂无评论...
验证码 换一张
取 消