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

I am using the Net::Telnet module to telnet to several boxes in a while loop. The whole idea is to grep some of the processes running there and returning the output.

sometimes one of the boxes doesn't answer for one reason or another and the program dies with the error message "timed-out waiting for login prompt at ..." How do I catch the timeout error and continue looping through the rest of the boxes?

Here's part of the code

while(<IN>){
    chomp ($num = $_);

    use Net::Telnet (); 
    $t = new Net::Telnet (Timeout => 10,
			  Prompt => '/.*# $/') or warn "timeout\n"; #this doesn't work.
    $t->open("10.0.0.$num") || die "can't telnet to $num\n";
    $t->login('$login','$pwd');

Thanks HeffaK

Replies are listed 'Best First'.
Re: Catching timeout for Net::Telnet
by no_slogan (Deacon) on May 09, 2001 at 22:13 UTC
    eval { $t = Net::Telnet->new(...); $t->open(...); # and so on }; warn $@ if $@;
    $@ holds any error message the stuff inside the eval {} might have died with.
      It did not work the way I used it...it still just dies.
      Any more ideas...
      heres the modified code..
          use Net::Telnet (); 
       eval {
          $t = Net::Telnet ->new(Timeout => 10,
      			  Prompt => '/.*# $/');
      };
      warn $@ if $@;    
      $t->open("10.0.0.$num") || die "can't telnet to $num\n";
          $t->login('$log','$pwd');
          $t->cmd("cd /home/dir");
      
          @lines = $t->cmd("ps uax");
      ...
      
      Thanks. HeffaK
        Go back and re-read my original post. You need to move all the operations on $t inside the eval {}. It's probably the open or login that's die()ing, not the Net::Telnet->new, anyway.

        If there's a failure at some point, you probably want to give up on the entire telnet session. After all, if the login fails, what's the chance of "cd /home/dir" working? If you put everything in the eval {}, the first one that dies will jump to the end of the eval block, skipping over the other commands.

Re: Catching timeout for Net::Telnet
by danichka (Hermit) on May 10, 2001 at 00:10 UTC
    I would try
    $t->errmode("return");
    This seems like it would help.
Re: Catching timeout for Net::Telnet
by TeKk9 (Scribe) on May 10, 2001 at 00:05 UTC
    I used some forking code to take care of a similar situation like this
    foreach my $market (@HOSTLIST) { if( my $mypid = fork() ) { print("$market is pid $mypid\n"); } elsif( $mypid == 0 ) { new_session($market); } elsif( ! defined $mypid ) { die "Error: Couldn't fork: $!"; }
    Mix it in with a procedure to sleep five minutes and try again for failed attempts and a max number of 3 retries.