o_chfa has asked for the wisdom of the Perl Monks concerning the following question:

OK here I'm again with regex and matching - but it's so strange I regarded suitable to open a new thread. To make it short: pattern matching works with variable and some lines down - all of a sudden - not. Even quotemeta doesn't mitigate the problem. Here comes a part of the code:

# some declarations in the beginnings my $TAB = "\t"; my $SPACE = " "; my $oidNbrSysDescr = ".1.3.6.1.2.1.1.1"; my $prefixSysDescr = quotemeta 'system.sysDescr.0 : DISPLAY S +TRING- (ascii): '; #my $prefixSnmpWalk = 'snmpwalk:\s*'; # no use ?? ... foreach $hostName (@serverList) { # snmpwalk as filehandle #---------------------------------- $FH_SNMPWALK = new FileHandle "$SNMPWALK $hostName $oidNbrSysDescr + 2>&1|"; die "$0: $! in Zeile: ", __LINE__ unless defined $FH_SNMPWALK; # execute snmpwalk #---------------------------------- while( $sysDescr = <$FH_SNMPWALK> ) { chomp $sysDescr; for ( $sysDescr ) { /$prefixSysDescr/ && do { s/$prefixSysDescr/$hostName$TAB/; $OutputLine = $_; last; }; # substitute some prefixes (this one works) /snmpwalk:\s*/ && do { s/snmpwalk:\s*/$hostName$TAB/; $OutputLine = $_; last; }; # error messages starting with "snmpwalk: " # here is the problem. All of a sudden I coudln't # use $prefixSnmpWalk anymore. Even quotemeta # failed $OutputLine = $OutputLine . $SPACE . $_; } # process output } # get system description with snmpwalk push( @{$serverSystemDescription{$hostName}}, $OutputLine ); # snmpwalk finished #---------------------------------- close $FH_SNMPWALK; die "$0: $! in Zeile: ", __LINE__ unless defined $FH_SNMPWALK; } # get system description of each host and put it in to a array ...

any ideas ? Thx

Replies are listed 'Best First'.
Re: His strangeness regex
by Sewi (Friar) on Sep 04, 2009 at 07:22 UTC
    for ( $sysDescr ) {
    This line doesn't make any sense to me.
    Try adding a lot debug prints to your script and then look if every variable contains what you expect and if your script walks the ways you want. For example:
    foreach $hostName (@serverList) { print STDERR "--- Server: $hostName\n"; # snmpwalk as filehandle #---------------------------------- $FH_SNMPWALK = new FileHandle "$SNMPWALK $hostName $oidNbrSysDescr + 2>&1|"; die "$0: $! in Zeile: ", __LINE__ unless defined $FH_SNMPWALK; # execute snmpwalk #---------------------------------- while( $sysDescr = <$FH_SNMPWALK> ) { chomp $sysDescr; print STDERR " Desc: $sysDescr\n"; for ( $sysDescr ) { print STDERR " in_for: $_\n";
    Giving the output some intend makes it easier to read when debugging nested loop/if situations. As long as you have no clue what is going wrong, up to one print in each loop or if block is a good thing. In many cases, the processing works, but the output isn't what you expect. Monitoring your $OutputLine variable may also be a good idea.

    Besides of your probleme, you could shorten your code a little bit:

    if (s/$prefixSysDescr/$hostName$TAB/ or s/snmpwalk:\s*/$hostN +ame$TAB/) { $OutputLine = $_; last; }; # substitute some prefixes (this one works)
    ...or even shorter...
    if (s/($prefixSysDescr|snmpwalk:\s*)/$hostName$TAB/) { $OutputLine = $_; last; }; # substitute some prefixes

      With youre shorting it works now as I wanted it to do.

      for ( $sysDescr ) { s/$prefixSysDescr|$prefixSnmpWalk/$hostName$TAB/ && do { $OutputLine = $_; last; }; # substitute some prefixes $OutputLine = $OutputLine . $SPACE . $_; } # process output

      If I run the script with 3 hostnames, it produces now the following output (the IBM machine produces normally an output over a couple of lines):

      $ perl -w getSysDescr.pl 82 >>omServer1 Sun SNMP Agent, Ultra-80 Pause in (main). Go [y|Y]; Quit [q|Q]: y 82 >> omServer2 IBM PowerPC CHRP Computer Machine Type: 0x0800004c Pr +ocessor id: 00C9FC8A4C00 Base Operating System Runtime AIX version: 0 +5.03.0000.0060 TCP/IP Client Support version: 05.03.0000.0063 Pause in (main). Go[y|Y]; Quit [q|Q]: y 82 >>omServer3 No response arrived before timeout. Pause in (main). Go [y|Y]; Quit [q|Q]:q

      Nevertheless I'm still interested why now the use of the variable $prefixSnmpWalk works.

      Beside:never mind my avoiding the if-clause. In this case I try to avoid an if-then-elseif-elseif .... I prefer select-case-else-endselect and substitute it with the for-loop

        Nevertheless I'm still interested why now the use of the variable $prefixSnmpWalk works.

        In the code you showed it always worked, your problem was always the input

        # some declarations in the beginnings my $TAB = "\t"; my $SPACE = " "; my $oidNbrSysDescr = ".1.3.6.1.2.1.1.1"; my $prefixSysDescr = quotemeta 'system.sysDescr.0 : DISPLAY S +TRING- (ascii): '; my $prefixSnmpWalk = 'snmpwalk:\s*'; # no use ?? my $sysDescr = q~ snmpwalk: yeah ~; for ( $sysDescr ) { /$prefixSysDescr/ && do { s/$prefixSysDescr/$hostName$TAB/; $OutputLine = $_; last; }; # substitute some prefixes (this one works) # /snmpwalk:\s*/ /$prefixSnmpWalk/ && do { s/snmpwalk:\s*/$hostName$TAB/; $OutputLine = $_; last; }; # error messages starting with "snmpwalk: " # here is the problem. All of a sudden I coudln't # use $prefixSnmpWalk anymore. Even quotemeta # failed $OutputLine = $OutputLine . $SPACE . $_; } # process output die "$OutputLine "; __END__ yeah at - line 36.
        Sometimes I stumble upon these sorts of hitches, something works just to stops working without prior warning, so my friend, I advice you to really dig into finding out how that shortening worked and where your problem resided in order to be able to avoid falling in the same pit over and over.

        Take care and have a happy Perl Programming :)


        Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.
Re: His strangeness regex
by Anonymous Monk on Sep 04, 2009 at 06:19 UTC
    In the fragment you've shown the problem is the data in $_, it isn't what you expect.

    You should write a program that compiles, with sample data, that demonstrates the problem you're having.