andrewarnier
andrewarnier

Reputation: 177

Use of uninitialized value in concatenation (.) or string at or string at

I've this error:

Use of uninitialized value $index in concatenation (.) or string at getdesc.pl line 43, <OctetsIn> line 2.

part of my code as follows:

my $select_sth = $dbh->prepare("SELECT Hid,Hostname,IP FROM Devices")
    or die "$dbh->errstr";
$select_sth->execute() or die "$dbh->errstr";
while ( my $row_ref = $select_sth->fetchrow_hashref ) {
    my $hostname = $row_ref->{'Hostname'};
    if ( $hostname ne 'null' ) {
        my $hid   = $row_ref->{'Hid'};
        my $ip    = $row_ref->{'IP'};
        my $desc  = "null";
        my $index = 0;
        open( OctetsIn, "snmpwalk -v2c -c public $ip 1.3.6.1.2.1.18 |" )
            or die "can't exec: $!";
        while (<OctetsIn>) {
            chomp;
            print <OctetsIn> . "\n";
            /IF-MIB::ifAlias.(\S+) = STRING: (\S+)/;
            $index = $1;
            $desc  = $2;
            $dbh->do(
                "INSERT INTO Description (Hid,index,desc) Values ($hid,$index,'$desc')"
            ) or die "$dbh->errstr";
        }
    }
}

close(OctetsIn);

What error is there in my code? anyone knows how to fix the error ?

The error is on the line:

$dbh->do("INSERT INTO Description (Hid,index,desc) Values ($hid,$index,'$desc')") or die "$dbh->errstr";

Upvotes: 0

Views: 1011

Answers (3)

Miller
Miller

Reputation: 35208

There are three issues regarding your innermost while loop:

  1. You're reading from the filehandle twice when trying to just print the current line:

    while (<OctetsIn>) {
        chomp;
        print <OctetsIn> . "\n";    # Should be: print "$_\n";
    
  2. Always verify that your regular expression matched before using capture variables.

    /IF-MIB::ifAlias.(\S+) = STRING: (\S+)/;
    $index = $1;               # Will be undefined if regex doesn't match
    $desc  = $2;
    
  3. Use placeholders and bind values instead of manually including values in a SQL statement:

    Should aim to never interpolate values directly into a SQL statement like below:

    "INSERT INTO Description (Hid,index,desc) Values ($hid,$index,'$desc')"
    

To clean up these three issues, I'd transform your inner while loop to something like the following.

while (<OctetsIn>) {
    chomp;
    print "$_\n";
    if (my ($index, $desc) = /IF-MIB::ifAlias.(\S+) = STRING: (\S+)/) {
        $dbh->do(
            "INSERT INTO Description (Hid,index,desc) Values (?,?,?)",
            undef, $hid, $index, $desc
        ) or die $dbh->errstr;
    }
}

Upvotes: 0

glezmen
glezmen

Reputation: 554

$index = $1;

your regexp doesn't match, so $1 is undef

Upvotes: 0

mpapec
mpapec

Reputation: 50677

You should test if regex was successful prior to assigning $1 to $index, ie.

 # skip to next line if current did not match, as $1 and $2 are undefined
 /IF-MIB::ifAlias.(\S+) = STRING: (\S+)/ or next;

Upvotes: 1

Related Questions