Проблема с дублированием результата в Perl - PullRequest
0 голосов
/ 09 августа 2011

Ниже приведен блок кода, с которым у меня в настоящее время возникают проблемы.

немного предыстории, я пишу скрипт, который будет проверять наши сетевые конфигурации, резервное копирование через прогорклый набор настроек по умолчанию / необходимости и выводить любые ошибки в электронное письмо.

Он работает, читая файл (имя файла хранится в виде $ configs), затем я использую выражения регулярного выражения, чтобы проверить наличие / отсутствие строки конфигурации.

Блок кода ниже должен сделать следующее.

Откройте дескриптор файла, затем, пока файл открыт, найдите все строки между следующими двумя частями интерфейса Regex GigabitEthernet [1-9] / [0-48] и!

Затем следует проверить строки между двумя регулярными выражениями на наличие строк

регистрация статуса ссылки на событие статус связующего дерева событий портье Включение связующего дерева bpduguard

Если какая-либо из вышеперечисленных строк не находится между двумя элиминаторами регулярных выражений, она должна вставить соответствующее сообщение об ошибке в массив для последующей обработки и последующей отправки по электронной почте.

Хотя приведенный ниже блок кода, кажется, работает (sortof), я получаю дубликаты записей, которые, несомненно, имеют какое-то отношение к операторам push, находящимся внутри оператора while ..

Обычно я делал бы что-то подобное

  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

1 Ответ

3 голосов
/ 09 августа 2011

Во-первых, всегда используйте прагмы 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";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...