Perl,telnet和输出

时间:2014-08-12 14:27:14

标签: perl telnet

我很难找到为什么我的perl脚本没有正确处理输出。

因此,代码(根据建议的更改进行了更新):

sub telnet_connection{


    my $targetHost = $_[0]; 
    #my $uname = $_[1];
    #my $pword = $_[2];
    my @listOfCommands = @{$_[3]};

    if($verbose){print "\t\tAttempting telnet connection to $targetHost\n"; }

    eval{
            $telnet = Net::Telnet->new( Timeout=>5, Errmode=>'return', dump_log=>"dump_log.txt", input_log=>"input_log.txt");
            $telnet->open($targetHost);
            $telnet->waitfor('/Username: $/i');
            $telnet->print($username);
            $telnet->waitfor('/PASSCODE: $/i');
            $telnet->print($password);
            $telnet->waitfor('/\>/');


            #for(my $j=0; $j le scalar @listOfCommands; $j++)
            for my $command (@listOfCommands)
            {
                if($verbose) { print "\t\tClient: " . $targetHost . " Command:  $command\n"; }
                if($verbose) { print "\t\tExecuting command: $command\n"; }
                my @output = $telnet->cmd($command);

                if($verbose) 
                { 
                    print "OUTPUT:\n";
                    print "@output\n"; 
                }
                logging($targetHost, \@output, "0");
            }
            $telnet->close();
        };
        if($telnet->errmsg)
        {
            logging($targetHost,$telnet->errmsg,"1");
            print $@;
        }
}

这是我编写的一个方法,它接受四个参数,即telnet连接的目标,用户名,密码和命令数组。 目前,我只是使用全局用户名和密码(分别是$ username $ password),因为存在其他问题。 $ verbose是我传递的标志,在这种情况下它被设置为true。 logging是我写的另一种处理输出的方法,但是当$ verbose为true时,我应该在控制台上看到它。代码能够进行身份验证,并运行命令,但我的输出不是当下。当我检查dump_log和input_log时,原始(和格式化)文本存在,并显示我实际执行命令并看到输出,但是,当我尝试检查输出时,它返回一个"":

Telnet to <targetIPAddress>
        Attempting telnet connection to <targetIPAddress>
        Client: <targetIPAddress> Command:  who
        Executing command: who
OUTPUT:

我只是不确定从何处进行故障排除。我已经查看了Perl中Telnet上已有的几个堆栈溢出帖子,但是在那里找不到多少帮助。

2 个答案:

答案 0 :(得分:5)

  

我只是不确定从何处进行故障排除。

嗯,你错过了最明显的Perl故障排除技巧。将以下两行添加到您的程序中。

use strict;
use warnings;

您会收到一些错误消息,说明您尚未声明变量。其中大多数都很简单,可以修复。但重要的一个接近尾声。你有:

my @output = $telnet->cmd($listOfCommands[$j]);

然后是:

print "$output\n"; 

logging($targetHost, $output, "0");

@output是一个数组。 $output是一个标量。它们是两个不同的变量,彼此没有联系。

其他一些提示:

$telnet = new Net::Telnet (...);

最好写成:

$telnet = Net::Telnet->new(...);

我知道该模块的文档使用的是前一版本,但这是一个非常糟糕的主意,并且很有可能在将来破坏它。

另外,你的循环:

for(my $j=0; $j le scalar @listOfCommands; $j++)
{
    # stuff using $listOfCommands[$j]
}

最好写成:

foreach my $command (@listOfCommands)
{
    # stuff using $command
}

答案 1 :(得分:0)

通过Perlmonks,我发现了这个问题。详情如下:

http://perlmonks.org/?node_id=1097296

在telnet语句的声明中,必须包含提示符,以便命令解释器知道命令输出何时完成(通过正则表达式运行)。

$telnet = Net::Telnet->new( Timeout=>5, Errmode=>'return', dump_log=>"dump_log.txt", input_log=>"input_log.txt");

需要成为:

$telnet = Net::Telnet->new( Timeout=>5, Errmode=>'return', dump_log=>"dump_log.txt", input_log=>"input_log.txt", prompt=>'/\>/');