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

Hello!!! I am new to perl, enjoying it but having a few problems.
I am trying to create a program which telnets to a bunch of routers / switches, runs some commands and then outputs to a text file. I currently have the program reading the logon info from an excel doc. Should be simple?...
My problem is that when a telnet session fails the program stops. What I want it to do is Output to the user that it has failed and then carry on to the next router/switch in the excel doc. Is there something that the telnet outputs that I can use to recognise it has failed? Or maybe if it hasn't done anything for 10 seconds go to next item in the for loop.
Thanks for you help :)

#!/usr/bin/perl require Net::Cisco; use Win32::OLE qw(in with); use Win32::OLE::Const 'Microsoft Excel'; my $Router_Ip; my $Router_User; my $Router_Logon; my $Router_Enable; my $Row; my $Col; my $NumDevices = &promptUser("Amount of devices to Telnet to?"); print ("Telneting to $NumDevices devices \n"); $Win32::OLE::Warn = 3; # die on errors... # get already active Excel application or open new my $Excel = Win32::OLE->GetActiveObject('Excel.Application') || Win32::OLE->new('Excel.Application', 'Quit'); # open Excel file my $Book = $Excel->Workbooks->Open("c:/SCRIPTS/data.xlsx"); # select worksheet number 1 my $Sheet = $Book->Worksheets(1); #Read the excel spreadsheet and telnet to devices for ($i=1; $i<=$NumDevices; $i++ ){ $Row = $i; &readExcel(); &telnetRouter(); } # close excel doc $Book->Close; #------------------------------------------------# # SUB ROUTINES # #------------------------------------------------# # Read Excel doc and set Router Vars sub readExcel() { foreach my $Col (1..4){ use Switch; switch ($Col) { case 1 {$Router_Ip =$Sheet->Cells($Row,$Col)->{'Value'}} case 2 {$Router_User =$Sheet->Cells($Row,$Col)->{'Value'}} case 3 {$Router_Logon =$Sheet->Cells($Row,$Col)->{'Value'}} case 4 {$Router_Enable = $Sheet->Cells($Row,$Col)->{'Valu +e'}} } # skip empty cells next unless defined $Sheet->Cells($Row,$Col)->{'Value'}; $Sheet->Cells($Row,$Col)->{'Value'}, $Sheet->Cells($Row,$Col)->{'Formula'}; } } sub telnetRouter() { print ("\nAbout to telnet to Router:\nIP: $Router_Ip using:\nUN: + $Router_User \nPW: $Router_Logon \nEN: $Router_Enable \n"); my $session = Net::Telnet::Cisco->new(Host => $Router_Ip , Inp +ut_log =>"c:/SCRIPTS/$Router_Ip.log"); $session->login($Router_User, $Router_Logon); if ($session->enable($Router_Enable)){ @output = $session->cmd('show run | include username'); print ("Finished $Router_Ip Router Command \n"); } else { warn `Can’t enable:`. $session -> errmsg; } $session -> close; } sub promptUser { local($promptString,$defaultValue) = @_; if ($defaultValue) { print $promptString, "[", $defaultValue, "]: "; } else { print $promptString, ": "; } $| = 1; # force a flush after our print $_ = <STDIN>; # get the input from STDIN (presumably the ke +yboard) chomp; if ($defaultValue) { return $_ ? $_ : $defaultValue; # return $_ if it has a value } else { return $_; } }

Replies are listed 'Best First'.
Re: Telnet Question:
by dasgar (Priest) on Mar 04, 2011 at 06:17 UTC

    Although I have never used the Net::Cisco that your code is using, I've got a few thoughts that might help.

    Since you're apparently hitting issues with the telnet connection that is causing your program to stop, I'd suggest calling your "telnetRouter" subroutine from within an eval block and testing afterwards if an error occurred. Others might be able to give more useful tips on error trapping, such as using the Carp module.

    Another simpler route could be to see if the telnet module you're using provides a method for determining if a connection succeeded or not.

    If you're wanting your program to continue on to the next item without waiting, you might want to check out fork or threads.

    Just a few other thoughts and suggestions.

    • It would be a good idea to get in the habit of having use strict; and use warnings; at the beginning of your Perl code.
    • I'd suggest that you parse out the information that you need from the Excel file, store that information in variables and close Excel. Otherwise, if your program dies unexpectedly, you could be left with orphaned Excel processes that have your file open. --> Speaking from personal experience on this one. :D
    • You're using global variables instead of passing values into and out of your subroutines. I believe that it would probably be better to not be using global variables. (That's something that I'm personally working with the new stuff that I write. It's been a struggle for me at times because I'm notorious for using global variables myself.)

    Hopefully some of the above information/opinions will be helpful to you.

      Thank you for your advice. Very practical good advice. I am getting much closer to solving this problem. THANK YOU for your time!!!! :)