【问题标题】:Perl - Output the log filesPerl - 输出日志文件
【发布时间】:2015-11-21 13:07:05
【问题描述】:

我创建了一个远程登录到多个交换机的 perl。我想通过远程登录交换机来检查远程登录功能是否正常。

这是我远程登录到交换机的代码:

#!/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++;
}

这是我测试 7 个开关后的输出状态:

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

我想将 telnet 结果转换为日志文件。
perl如何区分telnet成功和失败的结果?

【问题讨论】:

  • 你为什么使用@output$count
  • 请开启use strict;——它和use warnings;一样重要。

标签: perl logging switch-statement telnet cisco


【解决方案1】:

请尝试以下方法

#!/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

【讨论】:

  • 太好了!!感谢您的帮助。
【解决方案2】:

在打印后的打印语句中,只需在代码中写入文件句柄名称OUTPUT

print OUTPUT "$switch Telnet success\n";

print OUTPUT "$switch $telnetstat\n";

附注:始终使用词法文件句柄和三个带有错误处理的参数来打开文件。这行open(OUTPUT, "&gt;log.txt");可以这样写:

open my $fhout, ">", "log.txt" or die $!;

【讨论】:

  • 修改后的输出状态如下 print OUTPUT "$switch Telnet success\n";.怎么了?
  • print() 在 ./testing7.pl 第 37 行, 第 2 行关闭文件句柄 OUTPUT。在 ./testing7.pl 第 37 行, 行关闭文件句柄 OUTPUT 上的 print() 3. ./testing7.pl 第 37 行, 第 4 行的已关闭文件句柄 OUTPUT 上的 print()。10.xxx.188.188 Telnet ./testing7.pl 第 37 行, 已关闭文件句柄 OUTPUT 上的 print() 失败第 6 行。
  • close 移到while 循环之外。
  • while 循环之外写入close(OUTPUT);
  • @DannyLuk:如果这对你有帮助,你可以接受这个作为答案,所以它可以接近解决。 :)
【解决方案3】:

使用Sys::Syslog 写入日志消息。

但是由于您正在使用句柄 OUTPUT 打开一个 log.txt 文件,因此只需将您的两个 print 语句更改为将 OUTPUT 作为第一个参数,将字符串作为下一个参数(不带逗号)。

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");

您可以考虑将close 移动到END 块:

END {
  close(OUTPUT);
}

不仅因为它在您的 while 循环中。

【讨论】:

  • 为什么需要END 块,而不是仅仅在循环之外?
  • 一个 END 代码块被尽可能晚地执行,也就是说,在 perl 完成程序运行之后并且在解释器即将退出之前,即使它是由于 die( ) 功能。 perldoc.perl.org/…
  • 是的,我知道END 是什么。我只是质疑你为什么在这里使用它,而不是仅仅将close 放在循环之外。这似乎是多余的。
  • @Sobrique 打开 OUTPUT 后的下一行可能会死掉......我的意思是,实际上 perl 非常擅长清理,所以你可能永远不会遇到问题。
猜你喜欢
  • 1970-01-01
  • 2012-04-21
  • 2013-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-28
  • 2015-01-29
相关资源
最近更新 更多