Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Use of uninitialized value $brip in join or string at script.pl line 50

by deep27ak (Novice)
on Sep 15, 2015 at 16:43 UTC ( [id://1142098]=perlquestion: print w/replies, xml ) Need Help??

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

I have a script as below
#!/usr/bin/perl -w use strict; use warnings; use XML::Simple; my $xml = do {local $/='';'network.xml'} ; my $servers = XMLin($xml, ForceArray => 1); my %seen; foreach my $server (@{$servers->{server}}) { my $brlist; my $corebrip; my $brmask; my $brip; my $num; my $brlan; my @node = $server->{NodeName__1} . "\n"; my $lanip = $server->{CoreLanIP_1__1} ; my @mask = $server->{CoreLanNetmask_1} . "\n"; my $network = join("/", $lanip, @mask); $network =~ s/.[0-9]*\//.0\//g; push(my @networklist, $network) if ! $seen{$network}++; $brlan = $server->{BRLAN} ; if ( $brlan eq "y" ) { $brip = $server->{BR_IP}; $num = $server->{CoreLanNum} ."\n" ; } my @brnwlist; for my $n (1..$num){ $corebrip = $server->{'CoreLanIP_'.$n.'__1'} ; $brmask = $server->{'CoreLanNetmask_'.$n} ."\n"; } if ( $corebrip eq $brip ){ $brlist = join ("/", $brip, $brmask) ; $brlist =~ s/.[0-9]*\//.0\//g; push( @brnwlist, $brlist) unless $seen{$brlist}++; } else { print "coreip doesnot matches brip\n"; } } for $a (@brnwlist) { if ( $a ne "") { print "empty array"; my $vnum = $server->{CoreVlanNum} ."\n" ; for my $i (1..$vnum){ my $vlanip = $server->{'CoreVlan_IP_'.$i} ; my $vmask = $server->{'CoreVlan_Netmask_'.$i} ."\n"; if ($vlanip eq $brip){ my $vlist = join ("/", $brip, $vmask) ; $vlist =~ s/.[0-9]*\//.0\//g; push(my @vnwlist, $vlist) if ! $seen{$vlist}++; print @vnwlist; } } } } }

Now I am not able to figure out how to define the variable globally grepped from xml so that they can be used anywhere inside my script.

Most importantly I have to run a 'if' condition where if $brlan =y then there are two more conditions.

if the array from first for condition i.e. @brnwlist doesnot contains any value and is empty ( which should happen if $brip ne $corebrip) then second for loop should run searching for $vnum.

But I am not sure how to use these variables all across the foreach  my $server (@{$servers->{server}}) loop

my output at the moment
Use of uninitialized value $brip in string eq at nfs_security.pl line +48. Use of uninitialized value $brip in join or string at nfs_security.pl +line 50. Use of uninitialized value $brmask in join or string at nfs_security.p +l line 50. Use of uninitialized value $num in foreach loop entry at nfs_security. +pl line 44. Use of uninitialized value $corebrip in string eq at nfs_security.pl l +ine 48. Use of uninitialized value $brip in string eq at nfs_security.pl line +48. Use of uninitialized value $brip in join or string at nfs_security.pl +line 50. Use of uninitialized value $brmask in join or string at nfs_security.p +l line 50. Use of uninitialized value $num in foreach loop entry at nfs_security. +pl line 44. Use of uninitialized value $corebrip in string eq at nfs_security.pl l +ine 48. Use of uninitialized value $brip in string eq at nfs_security.pl line +48. Use of uninitialized value $brip in join or string at nfs_security.pl +line 50. Use of uninitialized value $brmask in join or string at nfs_security.p +l line 50. Use of uninitialized value $num in foreach loop entry at nfs_security. +pl line 44. Use of uninitialized value $corebrip in string eq at nfs_security.pl l +ine 48. Use of uninitialized value $brip in string eq at nfs_security.pl line +48. Use of uninitialized value $brip in join or string at nfs_security.pl +line 50. Use of uninitialized value $brmask in join or string at nfs_security.p +l line 50. Use of uninitialized value $num in foreach loop entry at nfs_security. +pl line 44. Use of uninitialized value $corebrip in string eq at nfs_security.pl l +ine 48. Use of uninitialized value $brip in string eq at nfs_security.pl line +48. Use of uninitialized value $brip in join or string at nfs_security.pl +line 50. Use of uninitialized value $brmask in join or string at nfs_security.p +l line 50. coreip doesnot matches brip coreip doesnot matches brip coreip doesnot matches brip coreip doesnot matches brip coreip doesnot matches brip coreip doesnot matches brip coreip doesnot matches brip coreip doesnot matches brip
Input xml
<servers> <server NodeName__1="mch30-nds-ins" CoreLanNum="2" CoreBondNum="1" CoreVlanNum="1" CoreVlan_IF_1="vlan2603" CoreVlan_IP_1="192.168.156.16" CoreVlan_Netmask_1="255.255.255.0" CoreLanIP_1__1="192.168.156.16" CoreLanNetmask_1="255.255.255.0" CoreLanIP_2__1="192.168.156.16" CoreLanNetmask_2="255.255.255.0" BRLAN="n" /> <server NodeName__1="mch30-nds-insc" CoreLanNum="2" CoreBondNum="1" CoreVlanNum="2" CoreVlan_IF_1="vlan2605" CoreVlan_IP_1="192.168.156.16" CoreVlan_Netmask_1="255.255.255.0" CoreLanIF_1="eth0" CoreLanIP_1__1="192.168.156.16" CoreLanNetmask_1="255.255.255.0" CoreLanIP_2__1="192.168.156.16" CoreLanNetmask_2="255.255.255.0" BR_IP="192.168.165.16" BR_Interface="vlan3525" BRLAN="y" /> <server NodeName__1="nds-test" CoreLanNum="4" CoreBondNum="2" CoreVlanNum="0" CoreLanIP_1__1="192.169.32.1" CoreLanNetmask_1="255.255.255.0" CoreLanIP_2__1="192.169.32.1" CoreLanNetmask_2="255.255.255.0" BR_IP="192.169.73.1" BRLAN="y" CoreLanIP_3__1="192.169.73.1" CoreLanNetmask_3="255.255.255.240" CoreLanIP_4__1="192.169.73.1" CoreLanNetmask_4="255.255.255.240" CoreLanBond__4="bond3" arp_Target_BnR_IP="192.169.73.254" RouteIP_1__1="192.169.73.0" RouteNetmask_1__1="255.255.255.0" RouteGateway_1__1="192.169.73.254" />

Replies are listed 'Best First'.
Re: Use of uninitialized value $brip in join or string at script.pl line 50
by stevieb (Canon) on Sep 15, 2015 at 17:05 UTC

    Welcome to the Monastery, deep27ak!

    At a glance, it appears as though you've got numerous issues with your code, including undefined variables, an erroneous }, repeatedly reassigning over a variable without using it in loops etc.

    Please post enough of a sample of the XML file you're using as input that will satisfy a single pass of the script. Without that, it's too time consuming to reconstruct the code properly.

    Also, get in the habit of using proper indenting. It'll help you greatly, and it'll help us work with what you've got.

    Here's an example:

    use strict; use warnings; use XML::Simple; my $xml = do {local $/='';'network.xml'} ; my $servers = XMLin($xml, ForceArray => 1); my %seen; foreach my $server (@{$servers->{server}}) { my $brlist; my $corebrip; my $brmask; my $brip; my $num; my $brlan; my @node = $server->{NodeName__1} . "\n"; my $lanip = $server->{CoreLanIP_1__1} ; my @mask = $server->{CoreLanNetmask_1} . "\n"; my $network = join("/", $lanip, @mask); $network =~ s/.[0-9]*\//.0\//g; push(my @networklist, $network) if ! $seen{$network}++; $brlan = $server->{BRLAN} ; if ( $brlan eq "y" ) { $brip = $server->{BR_IP}; $num = $server->{CoreLanNum} ."\n" ; } my @brnwlist; for my $n (1..$num){ $corebrip = $server->{'CoreLanIP_'.$n.'__1'} ; $brmask = $server->{'CoreLanNetmask_'.$n} ."\n"; } if ( $corebrip eq $brip ){ $brlist = join ("/", $brip, $brmask) ; $brlist =~ s/.[0-9]*\//.0\//g; push( @brnwlist, $brlist) unless $seen{$brlist}++; } else { print "coreip doesnot matches brip\n"; } } for $a (@brnwlist) { if ( $a ne "") { print "empty array"; my $vnum = $server->{CoreVlanNum} ."\n" ; for my $i (1..$vnum){ my $vlanip = $server->{'CoreVlan_IP_'.$i} ; my $vmask = $server->{'CoreVlan_Netmask_'.$i} ."\n"; if ($vlanip eq $brip){ my $vlist = join ("/", $brip, $vmask) ; $vlist =~ s/.[0-9]*\//.0\//g; push(my @vnwlist, $vlist) if ! $seen{$vlist}++; print @vnwlist; } } } }

    -stevieb

      Thanks very much for looking into this. Yes I understand it has multiple issues and I am still trying to evolve on scripting so I sure WILL take your advice in upcoming posts

      I have updated my question a trimmed version of xml although it contains all the necessary input required for the script.

      if BRLAN = y then first the script should search for CoreLanNum $n. and the loop should run as many times as $n and should match BR_IP with CorLanNum_IP and store the value in a array.

      If this array is empty run next for loop and search of CoreVlanNum $n and the script should again search for CoreVlanIP with BR_IP and map it with equivalent netmask.

        For the first server mch30-nds-ins there in no BR_IP attribute to match against.

        poj
Re: Use of uninitialized value $brip in join or string at script.pl line 50
by tangent (Parson) on Sep 15, 2015 at 18:39 UTC
    stevieb's approach is probably the way to go, however it assumes that if BR_IP = "n" then you go and search CoreVlanIP for matches. In the code below I assume that if BR_IP = "n" then do nothing, but if the @brnwlist is empty then search CoreVlanIP for matches. I have added some print statements and use Data::Dumper to show what is going on (a habit worth acquiring):
    use Data::Dumper; my $count = 1; foreach my $server (@{$servers->{server}}) { print "\nCount: ", $count++, "\n"; my $brlan = $server->{BRLAN} ; print "brlan = $brlan\n"; next unless $brlan eq "y"; my $brip = $server->{BR_IP}; my $num = $server->{CoreLanNum}; my $corebrip = $server->{'CoreLanIP_'.$num.'__1'} ; my $brmask = $server->{'CoreLanNetmask_'.$num}; my @brnwlist; for my $n (1..$num){ $corebrip = $server->{'CoreLanIP_'.$n.'__1'} ; if (not $corebrip) { print "CoreLanNum $n - No value for CoreLanIP_".$n."__1\n" +; next; } print "CoreLanNum $n - brip: $brip, corebrip: $corebrip\n"; $brmask = $server->{'CoreLanNetmask_'.$n}; if ( $corebrip eq $brip ){ my $brlist = join ("/", $brip, $brmask) ; $brlist =~ s/.[0-9]*\//.0\//g; push( @brnwlist, $brlist) unless $seen{$brlist}++; } else { print "coreip does not match brip\n"; } } print "brnwlist: ", Dumper(\@brnwlist); next if @brnwlist; my @vnwlist; my $vnum = $server->{CoreVlanNum}; for my $i (1..$vnum){ my $vlanip = $server->{'CoreVlan_IP_'.$i}; if (not $vlanip) { print "CoreVlanNum $i - No value for CoreVlan_IP_$i\n"; next; } print "CoreVlanNum $i - brip: $brip, vlanip: $vlanip\n"; my $vmask = $server->{'CoreVlan_Netmask_'.$i}; if ($vlanip eq $brip){ my $vlist = join ("/", $brip, $vmask) ; $vlist =~ s/.[0-9]*\//.0\//g; push(my @vnwlist, $vlist) if ! $seen{$vlist}++; } else { print "vlanip does not match brip\n"; } } print "vnwlist: ", Dumper(\@vnwlist); }
    Output:
    Count: 1 brlan = n Count: 2 brlan = y CoreLanNum 1 - brip: 192.168.165.16, corebrip: 192.168.156.16 coreip does not match brip CoreLanNum 2 - brip: 192.168.165.16, corebrip: 192.168.156.16 coreip does not match brip brnwlist: $VAR1 = []; CoreVlanNum 1 - brip: 192.168.165.16, vlanip: 192.168.156.16 vlanip does not match brip CoreVlanNum 2 - No value for CoreVlan_IP_2 vnwlist: $VAR1 = []; Count: 3 brlan = y CoreLanNum 1 - brip: 192.169.73.1, corebrip: 192.169.32.1 coreip does not match brip CoreLanNum 2 - brip: 192.169.73.1, corebrip: 192.169.32.1 coreip does not match brip CoreLanNum 3 - brip: 192.169.73.1, corebrip: 192.169.73.1 CoreLanNum 4 - brip: 192.169.73.1, corebrip: 192.169.73.1 brnwlist: $VAR1 = [ '192.169.73.0/255.255.255.240' ];

      Thanks very much stevieb and tangent.

      You guys made my day. I now understand the usage of variables and the place it should be defined. I did tried using subroutines but I believe my script requirement would be fulfilled more by the second method.

      Till now the script does works as expected with one loop hole as I see.

      After picking up unique values the output contains empty lines as below

      If vlannum exists
      vnwlist: $VAR1 = [ '192.168.165.0/255.255.255.0 ' ]; vnwlist: $VAR1 = []; vnwlist: $VAR1 = []; vnwlist: $VAR1 = []; vnwlist: $VAR1 = []; vnwlist: $VAR1 = []; vnwlist: $VAR1 = []; vnwlist: $VAR1 = [];
      if corelannum exists
      brnwlist: $VAR1 = [ '192.169.73.0/255.255.255.0 ' ]; brnwlist: $VAR1 = []; brnwlist: $VAR1 = []; brnwlist: $VAR1 = []; brnwlist: $VAR1 = []; brnwlist: $VAR1 = [];
      I tried various provided here http://www.perlmonks.org/?node_id=124970

      but nothing seems to work in my case. At one point I have to dump these values in a file and with these empty lines it will not be proper.

      Also can someone please help me understand why do we use Data:Dumper ?

      my script
      for my $n (1..$num){ $corebrip = $server->{'CoreLanIP_'.$n.'__1'} ; if (not $corebrip) { print "CoreLanNum $n - No value for CoreLanIP_".$n."__1\n" +; next; } # print "CoreLanNum $n - brip: $brip, corebrip: $corebrip\n"; $brmask = $server->{'CoreLanNetmask_'.$n} . "\n" ; if ( $corebrip eq $brip ){ $brlist = join ("/", $brip, $brmask) ; $brlist =~ s/.[0-9]*\//.0\//g; push( @brnwlist, $brlist) unless $seen{$brlist}++; } else { # print "coreip doesnot matches brip\n"; } } print "brnwlist: ", Dumper(\@brnwlist); next if @brnwlist; my @vnwlist; my $vnum = $server->{CoreVlanNum}; for my $i (1..$vnum){ my $vlanip = $server->{'CoreVlan_IP_'.$i} ; if (not $vlanip) { # print "CoreVlanNum $i - No value for CoreVlan_IP_$i\n"; next; } # print "CoreVlanNum $i - brip: $brip, vlanip: $vlanip\n"; my $vmask = $server->{'CoreVlan_Netmask_'.$i} . "\n"; if ($vlanip eq $brip){ my $vlist = join ("/", $brip, $vmask) ; $vlist =~ s/.[0-9]*\//.0\//g; push @vnwlist, $vlist unless $seen{$vlist}++; } } @vnwlist = grep (/\S/, @vnwlist); print "vnwlist: ", Dumper(\@vnwlist); } }
Re: Use of uninitialized value $brip in join or string at script.pl line 50
by stevieb (Canon) on Sep 15, 2015 at 18:05 UTC

    I played around for a bit and did a bunch of cleanup. I'm not sure if this does exactly what you're after, but it shows a much better structure that you should be able to follow.

    The biggest thing is that I got rid of all the variable definitions near the top. It's much easier to troubleshoot when you declare your variables immediately before use where possible.

    This code surely needs more work, but I did what I could with the time I had. Also note that it doesn't look like you use @networklist, but I left it in anyways.

    use strict; use warnings; use XML::Simple; use Data::Dumper; my $xml = do {local $/='';'in.xml'} ; my $servers = XMLin($xml, ForceArray => 1); my %seen; my @networklist; my @brlist; my @vlist; for my $server (@{$servers->{server}}){ my $node = $server->{NodeName__1}; my $lanip = $server->{CoreLanIP_1__1}; my $mask = $server->{CoreLanNetmask_1}; my $network = join("/", $lanip, $mask); $network =~ s/.[0-9]*\//.0\//g; push @networklist, $network if ! $seen{$network}++; if ($server->{BRLAN} eq "y" ){ core_lan($server); } else { core_vlan($server); } } # output print "\nBRNW LIST\n"; print Dumper \@brlist; print "\nVLAN LIST\n"; print Dumper \@vlist; exit(0); # # subroutine definitions # sub core_lan { my $server = shift; my $brip = $server->{BR_IP}; my $num = $server->{CoreLanNum}; for (1..$num){ my $corebrip = $server->{'CoreLanIP_'.$_.'__1'}; my $brmask = $server->{'CoreLanNetmask_'.$_}; if ($corebrip eq $brip){ my $brlist = join ("/", $brip, $brmask); $brlist =~ s/.[0-9]*\//.0\//g; push @brlist, $brlist unless $seen{$brlist}++; } else { print "coreip doesnot matches brip\n"; } } } sub core_vlan { my $server = shift; my $brip = $server->{BR_IP}; my $vnum = $server->{CoreVlanNum}; for (1..$vnum){ my $vlanip = $server->{'CoreVlan_IP_'.$_}; my $vmask = $server->{'CoreVlan_Netmask_'.$_}; if ($brip && $vlanip eq $brip){ my $vlist = join ("/", $brip, $vmask); $vlist =~ s/.[0-9]*\//.0\//g; push @vlist, $vlist if ! $seen{$vlist}++; } } }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1142098]
Approved by stevieb
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (3)
As of 2024-04-24 04:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found