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

Monks,

I have a script that does what I want, but I was wondering if there is a cleaner way of writing this. I thought about putting it in a for(each) loop, but if the run subroutine is successfull, I don't want it to process any of the other ip's. I haven't figured a way to prevent this using a for loop. Anyway, I would appreciate any advice.
Also, you might wonder what 256 is. That is the error code that is returned if ssh fails.
#!/usr/bin/perl -w # Attempt to connect to the server on each interface until successfull use strict; use Net::SSH qw(ssh); my @host = qw[ 192.168.15.2 192.168.16.2 192.168.17.2 192.168.18.2 ]; my $stout; $stout = run($host[0]); if ($stout == '256'){ print "$host[0] not responding, trying $host[1]\n"; $stout = run($host[1]); if ($stout == '256'){ print "$host[1] not responding, trying $host[2]\n"; $stout = run($host[2]); if ($stout == '256'){ print "$host[2] not responding, trying $host[3]\n"; $stout = run($host[3]); } } } else{ exit; } sub run { my $host = $_[0]; my $user = 'root'; my $cmd = '/usr/local/scripts/temp.sh'; ssh("$user\@$host", $cmd); }
Thanks,

Dru

Replies are listed 'Best First'.
Re: Not Using So Many 'if' Statements
by insensate (Hermit) on Jan 09, 2003 at 19:15 UTC
    Why not:
    for(@host){ $stout = run($_); exit unless($stout == 256); print "$_ not responding, trying next host\n"; } print "all hosts not responding";

      exit is not really the to be preferred way of leaving a loop, as it completely exits the program and not only the loop.

      One should indeed rather use last.

      CountZero

      "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

        Right... last will break me out of my loop... but why not just exit as soon as I've accomplished the purpose of the script instead of adding an extra command?

        Update: Here's what I mean:
        Adding the last statement would require an additional conditional:
        my $success; for(@host){ $stout = run($_); unless($stout == 256) { $success++; last; } print "$_ not responding, trying next host\n"; } print "all hosts not responding" unless $success;
      Thank you, I knew there was MTOWTDI
(z) Re: Not Using So Many 'if' Statements
by zigdon (Deacon) on Jan 09, 2003 at 19:15 UTC
    seems ilke a loop to me. untested code ahead:
    my @host = qw[ 192.168.15.2 192.168.16.2 192.168.17.2 192.168.18.2 ]; my $stout; my $counter = 0; while ($stout = run($host[$counter])) { last unless $stout == 256; if ($counter < $@host) { print "$host[$counter] not responding, trying $host[$counter+1]\n" +; $counter++; } else { print "$host[$counter] not responding, no more hosts to try.\n"; last; } }

    just a side note, "$stout == '256'" forces perl to take the string 256 and make it into a number - the quotes are useless there.

    -- zigdon

Re: Not Using So Many 'if' Statements
by OM_Zen (Scribe) on Jan 09, 2003 at 20:16 UTC
    Hi ,

    foreach $stout(@host){ run($stout) == 256? print "$stout not responding" : exit() +; }
Re: Not Using So Many 'if' Statements
by Aristotle (Chancellor) on Jan 11, 2003 at 22:52 UTC
    The way I'd write this is thus:
    #!/usr/bin/perl -w use strict; use Net::SSH qw(ssh); use constant USER => 'root'; use constant CMD => '/usr/local/scripts/temp.sh'; for my $host (qw( 192.168.15.2 192.168.16.2 192.168.17.2 192.168.18.2 )) { (ssh(USER . '@' . $host, CMD) != 256) and last; warn "No response from $host\n"; }
    Of note is that your original code had == '256' comparisons, mixing a numerical operator with a string operand. Why? Either use == 256 (numerically compare against a number) or eq '256' (string comparison against a string). As you really mean the number 256 here, the former is the right choice, even though what you had works too. It does incur a pointless string-to-number conversion, but that's beside the point: you need to be aware of the difference because one day it will bite you if you treat them as interchangeable.

    Makeshifts last the longest.