我正在使用以下lib Net::SSH2
在大多数情况下,我可以连接到我的设备并获得输出OK。以下是相关代码:
sub logIntoDevice
{
my $self = shift;
my ($ssh2) = @_;
if(! $ssh2->connect($self->deviceIP))
{
say "Failed to connect to device:",$self->deviceIP;
$ssh2->disconnect();
exit 0;
}
if(! $ssh2->auth_password($self->usr, $self->pass))
{
say "Authentication Fail to ",$self->deviceIP;
$ssh2->disconnect();
exit 0;
}
my $channel = $ssh2->channel();
$channel->blocking(0);
$channel->shell();
return $channel;
}
sub sendCmd
{
my $self = shift;
my ($cmd,$channel) = @_;
my @cmdOutput;
print $channel "$cmd\n";
while (<$channel>)
{
chomp $_;
push(@cmdOutput, $_);
}
return @cmdOutput;
}
以下是我发给子的cmd。它们工作正常,输出写入文件确定。
$self->writeToFile($fileName,$self->sendCmd("show clock",$channel));
$self->writeToFile($fileName,$self->sendCmd("\n",$channel));
$self->writeToFile($fileName,$self->sendCmd("dir",$channel));
除了我发送以下cmd的时候:
$self->writeToFile($fileName,$self->sendCmd("sh run",$channel));
使用putty在设备上输出cmd是:
sh run
Building configuration...
Current configuration : 16575 bytes
!
!
!Last configuration change at 16:37:19 CET+1 Sat Mar 15 2014
.....
但是在日志文件中你看到的只是
sh run
Building configuration...
所以问题是Building configuration
输出后的空白行使while (<$channel>)
认为它是输出的结尾。
我的问题是我无法在不使用While循环的情况下找到循环数据的方法。
的更新 的
好的拿出这个解决方案,但看起来非常笨重。如果这样做必须是一个更好的方法
sub sendCmd
{
my $self = shift;
my ($cmd,$channel) = @_;
my @cmdOutput;
my $currPrompt;
#get prompt. i am sure there is a better way!!! just cant figure it out
print $channel "\n";
while (<$channel>)
{
$currPrompt = $_;
}
print $channel "$cmd\n";
while(42)
{
my $inerOutput;
while (<$channel>)
{
chomp $_;
$inerOutput = $_;
push(@cmdOutput, $_);
}
if($inerOutput ne $currPrompt)
{
sleep(7);
}
else
{
last;
}
}
return @cmdOutput;
}
答案 0 :(得分:0)
我认为你的问题不是空白。最有可能的问题是,您使用的是非阻塞模式,设备执行命令需要一些时间。因此,在#34;构建配置之后,你得到一个空行(或一个undef)...&#34;因为没有产生额外的输出而被读取。
我会使用Net :: SSH2的轮询方法和超时,这会让你知道什么时候有东西要读。如果&#34; sh run&#34;需要比你发出的其他命令长得多,你的sendCmd方法需要知道这一点,并且在它决定不再有输出的时候允许更多时间通过。
或者,您可以(在使用时自定义,例如Net :: Telnet)等待更多输出,直到您看到提示,无论提示有关设备是什么, 然后你会知道命令已经完成执行。
答案 1 :(得分:0)
libss2_poll已被弃用