2

I have created a perl that telnet to multiple switches. I would like to check if telnet functions properly by telneting the switch.

This is my code to telnet to the switches:

#!/usr/bin/perl
use warnings;
use Net::Cisco;

open( OUTPUT, ">log.txt" );
open( SWITCHIP, "ip.txt" ) or die "couldn't open ip.txt";

my $count = 0;

while (<SWITCHIP>) {
    chomp($_);
    my $switch = $_;
    my $tl     = 0;
    my $t      = Net::Telnet::Cisco->new(
        Host => $switch,
        Prompt =>
            '/(?m:^(?:[\w.\/]+\:)?[\w.-]+\s?(?:\(config[^\)]*\))?\s?[\$#>]\s?(?:\(enable\))?\s*$)/',
        Timeout => 5,
        Errmode => 'return'
    ) or $tl = 1;

    my @output = ();
    if ( $tl != 1 ) {
        print "$switch Telnet success\n";
    }
    else {
        my $telnetstat = "Telnet Failed";
        print "$switch $telnetstat\n";
    }
    close(OUTPUT);
    $count++;
}

This is my output status after I was testing 7 switches:

10.xxx.3.17 Telnet success
10.xxx.10.12 Telnet success
10.xxx.136.10 Telnet success
10.xxx.136.12 Telnet success
10.xxx.188.188 Telnet Failed
10.xxx.136.13 Telnet success

I would like to convert the telnet result as log file.
How to separate successful and failed telnet results by using perl?

serenesat
  • 4,611
  • 10
  • 37
  • 53
Danny Luk
  • 47
  • 1
  • 3
  • 11

3 Answers3

1

In print statement after print just write the filehandle name which is OUTPUT in your code:

print OUTPUT "$switch Telnet success\n";

and

print OUTPUT "$switch $telnetstat\n";

A side note: always use a lexical filehandle and three arguments with error handling to open a file. This line open(OUTPUT, ">log.txt"); you can write like this:

open my $fhout, ">", "log.txt" or die $!;
serenesat
  • 4,611
  • 10
  • 37
  • 53
  • The output status as below after I revised print OUTPUT "$switch Telnet success\n";. Whats wrong? – Danny Luk Aug 27 '15 at 08:54
  • print() on closed filehandle OUTPUT at ./testing7.pl line 37, line 2. print() on closed filehandle OUTPUT at ./testing7.pl line 37, line 3. print() on closed filehandle OUTPUT at ./testing7.pl line 37, line 4. 10.xxx.188.188 Telnet Failed print() on closed filehandle OUTPUT at ./testing7.pl line 37, line 6. – Danny Luk Aug 27 '15 at 08:54
  • 2
    Move the `close` to outside the `while` loop. – Sobrique Aug 27 '15 at 09:06
  • Write `close(OUTPUT);` outside of `while` loop. – serenesat Aug 27 '15 at 09:07
  • @DannyLuk: If this helped you, you can accept this as an answer, so it can be close as solved. :) – serenesat Aug 28 '15 at 09:31
1

Please Try the following

#!/usr/bin/perl
use warnings;
use Net::Cisco;
################################### S
open( OUTPUTS, ">log_Success.txt" );
open( OUTPUTF, ">log_Fail.txt" );
################################### E
open( SWITCHIP, "ip.txt" ) or die "couldn't open ip.txt";

my $count = 0;

while (<SWITCHIP>) {
    chomp($_);
    my $switch = $_;
    my $tl     = 0;
    my $t      = Net::Telnet::Cisco->new(
        Host => $switch,
        Prompt =>
            '/(?m:^(?:[\w.\/]+\:)?[\w.-]+\s?(?:\(config[^\)]*\))?\s?[\$#>]\s?(?:\(enable\))?\s*$)/',
        Timeout => 5,
        Errmode => 'return'
    ) or $tl = 1;

    my @output = ();
################################### S
    if ( $tl != 1 ) {
        print "$switch Telnet success\n"; # for printing it in screen
        print OUTPUTS "$switch Telnet success\n"; # it will print it in the log_Success.txt
    }
    else {
        my $telnetstat = "Telnet Failed";
        print "$switch $telnetstat\n"; # for printing it in screen
        print OUTPUTF "$switch $telnetstat\n"; # it will print it in the log_Fail.txt
    }
################################### E
    $count++;
}
################################### S
close(SWITCHIP);
close(OUTPUTS);
close(OUTPUTF);
################################### E
Manu Mathew
  • 487
  • 4
  • 17
0

Use Sys::Syslog to write log messages.

But since you're opening a log.txt file with the handle OUTPUT, just change your two print statements to have OUTPUT as the first argument and the string as the next (without a comma).

my $telnetstat;
if($tl != 1) {
  $telnetstat = "Telnet success";
} else {
  $telnetstat = "Telnet Failed";
}
print OUTPUT "$switch $telnetstat\n";

# Or the shorter ternary operator line for all the above:
print OUTPUT $swtich . (!$tl ? " Telnet success\n" : " Telnet failed\n");

You might consider moving close to an END block:

END {
  close(OUTPUT);
}

Not only because it's in your while loop.

dlamblin
  • 43,965
  • 20
  • 101
  • 140
  • Why does that need an `END` block, as opposed to just being outside the loop? – Sobrique Aug 27 '15 at 09:06
  • An END code block is executed as late as possible, that is, after perl has finished running the program and just before the interpreter is being exited, even if it is exiting as a result of a die() function. http://perldoc.perl.org/perlmod.html#BEGIN%2c-UNITCHECK%2c-CHECK%2c-INIT-and-END – dlamblin Aug 27 '15 at 09:21
  • Yes, I know what `END` is. I'm just questioning why you're using it here, instead of just putting `close` outside the loop. It seems redundant. – Sobrique Aug 27 '15 at 09:25
  • @Sobrique The very next line after opening the OUTPUT might die... I mean, actually perl's pretty good about cleaning up, so you'd likely never have an issue. – dlamblin Aug 27 '15 at 09:28