【问题标题】:Need help getting output from Telnet to array in Perl需要帮助从 Telnet 获取输出到 Perl 中的数组
【发布时间】:2012-04-05 06:42:01
【问题描述】:

首先我想为这样一个愚蠢的问题道歉,但我对脚本很陌生。

我正在尝试做的事情: 在我的办公室,我正在尝试自动化恢复出厂重置开关的功能。其为开发商提供的测试设备不是生产设备仅供参考。我正在尝试将交换机的 telnet 提示符中的文件列表转储到一个数组中,然后过滤它们以保留我们的图像并删除其余的。

开关的常量和变量:本节的开关提示为=>,文件有扩展名和无扩展名,文件夹输出为foo\

我的问题: sub 没有正确发出 rm 命令,它在测试(打印值)中有效,但在实际删除脚本中无效。

新更新:

我知道我似乎放弃了这个问题,但我没有!上个月我一直在琢磨这个问题,并且取得了很大的成功。我已经能够将我的数据放入我的初始数组(是的,我有 2 个,稍后会详细介绍)。它将处理数组并删除我想要保留的内容。

#!/usr/bin/perl

$| = 1;

use Net::Telnet;
use strict;
use CGI;
use warnings;

my $junk;
my $telnet;
my @array;

#establish connection
$telnet = new Net::Telnet (Timeout=> 10,
                           Errmode=> 'return',
                           Port   => '2037');

$telnet->open('trn-13-mrv-con-07');
$telnet->put(chr(13));

#clear out buffered output for array to grab
$junk = $telnet->cmd(string => 'ls', prompt => '/=>/');
#array grabbing
@array = $telnet->cmd(string => 'ls', prompt => '/=>/');

#determining what the values are of the array
foreach my $item (@array) {
   #removing the carriage return
   chomp ($item);
   #if it's a folder, this will shunt the to the sub
   if ($item=~ /\//) {
       subfolders ($item);
       $telnet -> print("rm $item");
   }
   #checks to see if the file is the firmware for the switch
   elsif ($item =~ /btm.swi|secondary.swi/) {
   }
   #deletes the rest
   else {
    $telnet -> print ("rm $item");
    $telnet->put(chr(13));
   }
}

sub subfolders {
 my @subfolder_contents;
 my $subfolder = $_[0];
 my ($file, $sub_junk);

 #attempting to clear out the array
 undef @subfolder_contents;
 #again grabing any cached output so array can do it's work
 $sub_junk = $telnet ->cmd(string => "ls $subfolder", prompt => '/=>/');
 #grabbing files from the folder
 @subfolder_contents = $telnet ->cmd(string => "ls $subfolder", prompt => '/=>/');

 #deleting all files in the subfolder
 foreach $file (@subfolder_contents){
  chomp ($file);
    $telnet-> print ("rm $subfolder$file");
    $telnet->put(chr(13));

 }
};

exit;

这一切都非常好,而且这也适用于文件夹,主要是......如果文件夹为空或只有一个项目,它适用于文件夹。当文件夹中有 2 个或更多项目时,它不会发出正确删除该文件夹中文件的命令。

任何想法将不胜感激。谢谢! 谢谢!

【问题讨论】:

    标签: arrays perl telnet


    【解决方案1】:

    由于下面的讨论而编辑了答案

    问题确实是$t->put(chr(13)); 发送\r 会导致交换机响应另一个=> 提示,该提示现在在输出中。当您发出cmd 时,prompt 会导致第一行输出停止读取。

    empty_buffer 将不起作用,因为在您调用 cmd() 之前输入缓冲区中没有任何内容;它不是多线程应用程序。 cmd() 正在写,然后读。这是从套接字执行的第一次读取。如果您当时使用getline,那么您将拥有第一行,并且输入缓冲区将包含其余部分(或至少大部分内容取决于库中套接字读取的方式)

    如果不是使用cmd,而是使用print 或put 手动编写命令,然后使用循环和getline(),如果您绝对无法消除发送该命令,则可以忽略第一个=> \r

    【讨论】:

    • 感谢您的回复。我已经尝试过,结果相同。在过去的几周里,我可能已经阅读了大约 100 次该文档,哈哈。
    • 那么你的prompt 字符串有问题,我注意到你说的是"I found this out by changing the prompt variable to a file name and it captured and the script dumped all data up to that point"。我会测试它,但我的网络上没有运行 telnet 服务器的任何东西。
    • 我也是这么想的,但不仅仅是这个品牌或型号的开关,我在我们拥有的其他制造商 pf 开关上也得到了相同的结果。我们同时使用 procurve 和 H3C 交换机
    • 您能否编辑您的问题并发布一个终端会话的副本和粘贴,您可以在其中远程登录到交换机,然后执行ls?如有必要,您可以替换输出中的文件名。
    • 我已经更新了我的问题。我发现了一些有趣的东西。我删除了 $t->put(chr(13));从脚本中,它神奇地起作用了!好的,我知道这不是魔术,我认为这与缓冲区有关。我发出了 buffer_empty,但没有改进我的脚本。我会不使用 put 命令,但它只是更大脚本中的一小部分,所以我可能需要它。
    【解决方案2】:

    您可能希望停止捕获回显的输入。查看 Net::Telnet 文档中的 cmd_remove_mode。

    【讨论】:

    • 他是 - 这就是 prompt 参数的作用。
    • 这会拉出提示 - 但不是回显的“ls”条目。除非您的客户端执行本地回显或服务器将您的输入回显到显示器,否则您不会在 telnet 中看到您的输入。我猜这是在做后者。编辑:呃,没关系,我重新阅读了文档——你是对的,Net::Telnet 在内部匹配输入和尾随提示,应该只返回两者之间的内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-07
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    相关资源
    最近更新 更多