循环使用Net :: SSH2提供的数据

时间:2014-03-27 12:07:05

标签: perl net-ssh

我正在使用以下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;

}

2 个答案:

答案 0 :(得分:0)

我认为你的问题不是空白。最有可能的问题是,您使用的是非阻塞模式,设备执行命令需要一些时间。因此,在#34;构建配置之后,你得到一个空行(或一个undef)...&#34;因为没有产生额外的输出而被读取。

我会使用Net :: SSH2的轮询方法和超时,这会让你知道什么时候有东西要读。如果&#34; sh run&#34;需要比你发出的其他命令长得多,你的sendCmd方法需要知道这一点,并且在它决定不再有输出的时候允许更多时间通过。

或者,您可以(在使用时自定义,例如Net :: Telnet)等待更多输出,直到您看到提示,无论提示有关设备是什么, 然后你会知道命令已经完成执行。

答案 1 :(得分:0)

由于Net::SSH2->poll弃用

libss2_poll已被弃用