Hello Perl Monks

I've written a perl script that connects to a bunch of crusty old Cisco 877 routers and backs up their configuration over the WAN.

The script is below. The first part just parses the nagios status.dat file, which has the current public IP address of each router. Some of them have dynamic IP addresses and these are kept up to date through some passive checks in Nagios.

use warnings; use strict; open STATUS_DAT, "</usr/local/nagios4/var/status.dat"; my $hs = 0; my $r = 0; my $r_ip; my $r_name; my $NAME = 0; my $IP = 1; my @routers; sub write_config { my $config = shift; my $filename = shift; open CONFIG, ">$filename"; print CONFIG $config; print "Wrote $filename\n"; } while (<STATUS_DAT>) { $hs = 1, next if (/hoststatus/); $hs = 0, $r = 0, next if ($hs and /}/); next if (not $hs); $r = 1, $r_name = $+, next if (/host_name=(.*ROU)\n/); next if (not $r); $r_ip = $+, push @routers, [$r_name, $r_ip] if (/_PUBLICIP=[01];(. +*)\n/); } for my $router (@routers) { my $retries = 0; retry: my $output = `expect -f show_running_config.exp $router->[$IP]`; if ($? == 0) { write_config($output, "$router->[$NAME].cfg"); } else { if ($retries <= 3) { sleep 5; $retries++; goto retry; } else { print "Failed to get config for $router->[$NAME] at $route +r->[$IP]: $output\n"; } } }
The firmware on these routers does not handle SSH particularly well. Nagios is checking that the routers can be accessed using SSH over the WAN every 5 minutes. If you try and SSH into the router around 5-10 seconds after this check place, the connection is reset because the router is still tearing down the SSH session. The workaround in the script is to just try and connect in 5 seconds using a goto. I was wondering if there is a good way to rewrite this loop without goto? Or is goto OK in this case? I have had one idea, but the problem with it is it still waits 5 seconds even after the last retry has taken place before checking the next router:
for my $router (@routers) { my $retries = 0; while ($retries <= 3) { my $output = `expect -f show_running_config.exp $router->[$IP] +`; write_config($output, "$router->[$NAME].cfg"), last if ($? == +0); } continue { sleep 5; $retries++; } if ($retries > 3) { print "Failed to get config for $router->[$NAME] at $router->[ +$IP]: $output\n"; } }
Thanks in advance for any advice. Regards, Sam

In reply to Wait and retry loop without goto by samuelk1

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.