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

I have a script that cycles through several systems and collects the data of various shell commands. I do not know which systems will be up or have a SSH server running. Thus I need the script to skip any bad connections.
#!/usr/bin/perl use strict; use warnings; use Net::SSH::Perl; my ($ssh, $cmd, $x, $stdout, $stderr, $exit); # commands to be passed to remote server my @commands = ( 'uptime', 'tail /var/log/secure', 'tail /var/log/messages', 'exit'); my $user = 'root'; my $pass = 'root1'; open LOGFILE, "> hw-survey-log" || die "could not open file $!"; # connect to many hosts, on after another for ($x=3; $x<255; $x+=2){ # make new connection $ssh = Net::SSH::Perl->new("10.0.0.$x", protocol => 2) || next; $ssh->login($user, $pass) || next; print LOGFILE "\nHostname: 10.0.0.$x:\n"; # execute all commands foreach $cmd (@commands){ # pass command and record results ($stdout, $stderr, $exit) = ssh->cmd($cmd); print LOGFILE $stdout.$stderr.$exit; } } close LOGFILE;
I thought that the || next; would handle this. However, the script dies after the first attempt:
Can't connect to 10.0.0.3, port 22: No route to host at /usr/lib/perl5 +/vendor_perl/5.8.5/Net/SSH/Perl.pm line 206.
I can see in the pm code that there is a die:
connect($sock, sockaddr_in($rport, $raddr)) or die "Can't connect to $ssh->{host}, port $rport: $!";
It would be nice if there was a way around this without modifying the module.

Neil Watson
watson-wilson.ca

Replies are listed 'Best First'.
Re: Net::SSH::Perl and handling dead hosts
by Random_Walk (Prior) on Feb 16, 2005 at 15:08 UTC

    you could put your attempt to connect into an eval and catch the die

    eval {$ssh->login($user, $pass)}; next if $@;

    Cheers,
    R.

    Pereant, qui ante nos nostra dixerunt!
Re: Net::SSH::Perl and handling dead hosts
by friedo (Prior) on Feb 16, 2005 at 15:10 UTC
    How about wrapping it in an eval?

    for ($x=3; $x<255; $x+=2){ # make new connection eval { $ssh = Net::SSH::Perl->new("10.0.0.$x", protocol =>2); $ssh->login($user, $pass); }; next if $@; }

    Update: Nicer formatting.

Re: Net::SSH::Perl and handling dead hosts
by eXile (Priest) on Feb 16, 2005 at 16:04 UTC
    You could also try to use the Expect module to cope with unreliable input. There's a good tutorial on how to use it in the tutorials section.