Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Net::Telnet::cisco and pattern matching problem.

Status
Not open for further replies.

gindelhe

Technical User
May 23, 2002
9
0
0
US
Hello.

I have a script which logs into a PIX to check the number of connections and memory and then strips out what I don't need. But recently I have been having problems with the following error:
Use of uninitialized value in pattern match (m//) at fw.pl line 84, <STDIN> line 5.
Use of uninitialized value in pattern match (m//) at fw.pl line 91, <STDIN> line 5.

Here is the code I am using to get what I need from the PIX:
&process_input;
sub process_input
{
#
# Code to process the information from the PIX FireWall.
#
# Test output2
# Declaring variables and setting them to zero.

$in_use = 0;
$conn = 0;
$mem = 0;
#
# Processing now.
#
if ($output2[0] =~ /^\s*(\d+)\s+in use/) {
$in_use = $1;
}
# setting conn to special variable $1
$conn = $1;
$in_use = 0;
if ($output1[0] =~ /(\d+)\s+bytes free\s*$/) {
$in_use = $1;
}
}

Now my question is this:
Is there a way I can make sure the input I am getting is correct? The above code gets a series of numbers which I then manipulate into a simple to read format. Am I making enough sense in what I am asking?

Hal.
 
Hal,

$output2[0], and $output1[0] appear to be undef'd and that what Perl is warning you about.

Try a few debug print statements before your pattern matches to ensure the vars have values...
HTH

--Paul

It's important in life to always strike a happy medium, so if you see someone with a crystal ball, and a smile on their face ...
 
That helped somewhat. But I'm stil ltrying to figure out a way to trap this junk input before it goes on through the rest of my loops. Here is an input:

Use of uninitialized value in concatenation (.) or string at fw.pl line 93, <STDIN> line 5.
Output2 is
Use of uninitialized value in pattern match (m//) at fw.pl line 94, <STDIN> line 5.
Output1 is 268435456 bytes total, 87494656 bytes free

Use of uninitialized value in numeric le (<=) at fw.pl line 117, <STDIN> line 5.
Problem with getting input running again
Use of uninitialized value in concatenation (.) or string at fw.pl line 120, <STDIN> line 5.
Conn is
Mem is 87494656
Use of uninitialized value in numeric ge (>=) at fw.pl line 156, <STDIN> line 5.
Use of uninitialized value in formline at fw.pl line 378, <STDIN> line 5.

Since I have initialized $output1[0] and $output2[0] this has helped somewhat. Now I need to figure out a way to prevent this from happening so I can keep the input clean.

Thanks,
Hal.
 
Hal,

You posted the output from your script - can you post some sample data that's retrieved from your firewall box? That will likely make it easier to figure out what's wrong.
 
Ugh sorry about that. But what I am grabbing is the total amount of memory and the total connections. Here is a sample input that I get and then process from there:

Output2 is 13607 in use, 396980 most used

Output1 is 268435456 bytes total, 54460416 bytes free

I used the following code to strip out what I need:
&process_input;
sub process_input
{
#
# Code to process the information from the PIX FireWall.
#
# Test output2
# Declaring variables and setting them to zero.

$in_use = 0;
$conn = 0;
$mem = 0;
#
# Processing now.
#
print "Output2 is $output2[0] \n";
if ($output2[0] =~ /^\s*(\d+)\s+in use/) {
$in_use = $1;
}
# setting conn to special variable $1
$conn = $1;
$in_use = 0;
print "Output1 is $output1[0] \n";
if ($output1[0] =~ /(\d+)\s+bytes free\s*$/) {
$in_use = $1;
}
# Setting variable mem to special variable $1
$mem = $1;

What happens is that sometimes I get a NULL or none input and then it goes to mess up my script. I am thinking I need to put another check into my input to make sure that I am getting valid input. This is all I do in my sub routine that logs into the PIX and grabs the information:

# Log into the FireWall enable
$fw->enable($en_passwd);
$fw->cmd('/n');
@output1 = $fw->cmd('show memory');
#print @output1;
@output2 = $fw->cmd('show conn count');
#print @output2;
# log off firewall
$fw->cmd ('exit');

Hopefully this is more information.

Thanks,
Hal.
 
Maybe this will help a bit:

Code:
my $output1 = '268435456 bytes total, 54460416 bytes free';
my $output2 = '13607 in use, 396980 most used';

$output1 =~ /\s*(\d+)/;
my $mem = $1 || "Null";

$output2 =~ /\s*(\d+)/;
my $conn = $1 || "Null";

print "Memory in use: $mem\n";
print "Conns in use: $conn\n";

This will assign the value "Null" if the regex didn't match anything. An alternative, if you wanted the script to die if values are missing, you could change
Code:
my $mem = $1 || [red]"Null"[/red];
to
Code:
my $mem = $1 || [blue]die "No Memory Value"[/blue];
 
This Code posted by Rharsh works pretty good except for one part of it. I'm still trying to get my head wrapped around regex so here is the code and what I would like for it to do:
Code:
my $output1 = '268435456 bytes total, 54460416 bytes free';
my $output2 = '13607 in use, 396980 most used';

$output1 =~ /\s*(\d+)/;
my $mem = $1 || "Null";
I need to grap the second part of the memory it 54460416 bytes free. The current code grabs the first part which is the total memory. I need to grab the bytes free or the second number. Now is there a way to modify the code I was given to grab the second part of the output:
Code:
if ($output1[0] =~ /(\d+)\s+bytes free\s*$/) {
    $in_use = $1;
}
# Setting variable mem to special variable $1
$mem = $1;

Code:
$output2 =~ /\s*(\d+)/;
my $conn = $1 || "Null";
This works fine.

Sorry about this I am just trying to get this script to catch this oddity which recently started popping up.

Thanks,
Hal.
 
try this:-

Code:
#!/usr/bin/perl

$output1 = '268435456 bytes total, 54460416 bytes free';

if ($output1 =~ m|(\d+) bytes total|) {
  $output1_total = $1;
}

if ($output1 =~ m|(\d+) bytes free|) {
  $output1_free = $1;
}

print "\$output1_total => $output1_total\n";
print " \$output1_free => $output1_free\n";


Kind Regards
Duncan
 
If your code works fine except when it returns nothing, just try to test if the variable is defined before doing your match.....I don't totally understand your snippet of code though but try this with the defined function.
Code:
sub process_input
{
#
# Code to process the information from the PIX FireWall.
#
# Test output2
# Declaring variables and setting them to zero.

$in_use = 0;
$conn = 0;
$mem = 0;
#
# Processing now.
#
if ([highlight #FF99FF]defined($output2[0]) && [/highlight] $output2[0] =~ /^\s*(\d+)\s+in use/) {
    $in_use = $1;
}
# setting conn to special variable $1
$conn = $1; [COLOR=#ff0000]#Why not inside the if clause??????? so it can stay at 0 if nothing is found[/color]
$in_use = 0; [COLOR=#ff0000]# What's the use of this variable?????[/color]
if ([highlight #FF99FF]defined($output1[0]) && [/highlight]$output1[0] =~ /(\d+)\s+bytes free\s*$/) {
    $in_use = $1;
}
}

Cheers
 
I think this might do what you require:-

Code:
[b]#!/usr/bin/perl[/b]

my $storeVals;

my $output1 = '268435456 bytes total, 54460416 bytes free';
analyse(\$output1);

my $output2 = '13607 in use, 396980 most used';
analyse(\$output2);

sub analyse {

  $outputID = shift;
  
  print "checking : $$outputID\n";
  
  $storeVals{'bytes total'} = $1 if ($$outputID =~ m|(\d+) bytes total|);
  $storeVals{'bytes free'}  = $1 if ($$outputID =~ m|(\d+) bytes free|);
  $storeVals{'in use'}      = $1 if ($$outputID =~ m|(\d+) in use|);
  $storeVals{'most used'}   = $1 if ($$outputID =~ m|(\d+) most used|);
  
}

print "\n";

while (($key, $value) = each (%storeVals)) {
  print "$key => $value\n";
}

the hash won't store a value if it doesn't find one - try altering the bytes free to bytes available for example


Kind Regards
Duncan
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top