首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我认为perl中的Telnet输入缓冲区问题

我认为perl中的Telnet输入缓冲区问题
EN

Stack Overflow用户
提问于 2012-04-30 19:09:27
回答 1查看 2.4K关注 0票数 3

因此,在过去的一个月里,我一直在编写一个脚本来做主人清除惠普采购开关的工作。我已经和惠普内部的人谈过了,他们使用的系统和我完全不同,所以他们没有帮助。我想我都想通了。这就是我应该做的剧本:

bootrom.

  • changes

  • 建立一个远程连接,通过SNMP陷阱将

  • 重新引导交换机,并将其转储到一个数组H 212H 113数组中,H 113对数组执行数组H 212,对数组中的每一项运行一个程序,以识别固件,一个文件和一个文件夹A)忽略固件B)将每个文件添加到主删除数组C中)对文件夹中的文件运行类似的foreach,并将它们添加到主删除数组中,然后将它们添加到主删除数组中(用于删除purposes)

  • runs,用于删除主删除数组中的所有项以清除switch

  • reboots并在开关上设置基本信息。

)

更新

好的,所以我无法让$telnet->buffer_empty; 100%地工作,所以我决定调用第二个list命令并将其转储到一个垃圾文件中。下面是我的脚本,到目前为止,它正在我测试的10个开关上工作。我的夜班要打破开关测试这个重置脚本。

对任何感兴趣的人来说,这个脚本都是在惠普Pro曲线交换机上使用的,从我的研究来看,它将适用于他们中的大多数,但不是全部。

代码语言:javascript
复制
#!/usr/bin/perl
$| = 1;


use Net::Telnet;
use Net::SNMP;
use strict;
use CGI;

#variabls for power, connections and systemname
my $power_host     = ('Power-APC');
my $power_port     = ('Power-APC-Port');
my $system_name    = ('system-name');
my $console_server = ('Console-Server');
my $console_mgmtA  = ('Console-ManagementA');
my $match;
my ($garbage, $trash);
my $master_value;
my $telnet;
my @array;
my @master_array;


checkForNull("Console-Server",$console_server,1);
checkForNull("Console-ManagementA",$console_mgmtA,1);
checkForNull("Power_Host",$power_host,1);
checkForNull("Power_Port",$power_port,1);
checkForNull("System_Name", $system_name,1);


#Starting reset script
print("Please wait while $system_name resets.\n");
print("Please do not interact with any consoles open to this device\n");
print("The reset will take approximitly 5 minutes\n");

#establishing Telnet connection
$telnet = new Net::Telnet (Timeout=>120, Errmode=>'return', Port => $console_mgmtA);

$telnet->open($console_server);
sleep(1);

#executing reboot via SNMP
print("Deleting configuration files.\n");

   my ($snmp, $error) = Net::SNMP->session(
      -hostname  => shift || "$power_host",
      -community => shift || 'private',
      -port      => shift || 161
   );
   if (!defined($snmp)) {
      printf("ERROR: %s.\n", $error);
      exit 1;
   }
   my $sysx = ".1.3.6.1.4.1.318.1.1.12.3.3.1.1.4.$power_port";
   my $result = $snmp->set_request(
      -varbindlist => [$sysx, INTEGER, '3']
   );
   $snmp->close;




$telnet->waitfor(match=> '/Profiles/');
$telnet->cmd(string => '0', prompt => '/=>/');
#shift to compact flash card
$telnet->cmd (string=> 'cd cfa0', prompt => '/=>/');
my $garbage_output = $telnet -> cmd (string => 'ls', prompt => '/=>/');
$telnet->buffer_empty;


#propigates primary array with file list
undef @array;
@array = $telnet->cmd(string => 'ls', prompt => '/=>/');


#determines what should be deleted
foreach my $item (@array) {
    #cleans up the files for use in the if statement
   chomp ($item);
   #determines if it's a folder, passes folder name to sub
   if ($item=~ /\//) {
       subfolders ($item);
       #adds folder AFTER files in dir to ensure deletion
       push(@master_array, "rmdir $item");
   }
   #finds and ignores the primary and secondary firmware

   elsif ($item =~ /btm.swi|secondary.swi/) {
   }
   else {
    #adds all files to the master deletion list
    push(@master_array,"rm $item");
   }



#deletes all files listed in the master array
foreach $master_value (@master_array){
$telnet -> print ("$master_value");
}


#reboot switch
$telnet->print('boot');
$telnet->put(chr(13));
sleep(120);


#looking for ready screen
$telnet->waitfor(match=> '/continue/');
sleep (1);
$telnet->put(chr(13));
sleep (1);
$telnet->put(chr(13));
$telnet->waitfor(match=> '/continue/');
$telnet->put(chr(13));
$telnet->print('config');
$telnet->put(chr(13));
$telnet->print("hostname $system_name\n");
$telnet->print('lldp run');
$telnet->put(chr(13));
$telnet->print('wr mem');
$telnet->put(chr(13));
$telnet->print('boot');
$telnet->put(chr(13));
$telnet->print('y');


print("$system_name has been reset to factory settings.\n");
}


#add all files in folders to master deletion list
sub subfolders {
 my @subfolder_contents;
 my $subfolder = $_[0];
 my $file;

 @subfolder_contents = $telnet ->cmd(string => "ls $subfolder", prompt => '/=>/');
 foreach $file (@subfolder_contents){
  chomp ($file);
    push(@master_array, "rm $subfolder$file");
 }
};


sub checkForNull {
    my $name = $_[0];
    my $param = $_[1];
    my $required = $_[2];

    if($param eq "") {
        if ($required == 1) {
            print("\nSorry, no '$name' specified for this device, cannot continue.\n");
            exit 1;
        }
    }
# else {
 #       print("\n$name: $param\n");
  #  }
}

exit;
EN

回答 1

Stack Overflow用户

发布于 2012-05-01 05:04:43

有一个$telnet->buffer_empty可以满足您的要求,但我不认为这是您的问题(尽管尝试一下)。

你确定你的提示符不匹配得太快吗?换句话说,是否有一些也包含'=>‘的命令输出?最好的调试方法是通过$telnet->dump_log('/tmp/some_file'),它为您提供所有进出连接的十六进制转储(更重要的是,读取和写入Net::Telnet的确切顺序,这样您就可以知道它是否和在哪里匹配得太早)。

如果您与'=>‘提示符匹配得太早,只需尝试使正则表达式更加严格。添加'\z‘来检查字符串的结尾是一个很好的开始,但是如果'=>’后面有空格(比如'/=> ?\z/'),请小心。(当然,'\z‘并不是真正的“终结”,而是任何网络::Telnet到目前为止收集的东西。因此,如果输出中间的一个不吉利的包碰巧以“=>”结尾,那么它也会破坏更严格的正则表达式)

此外,您的长序列“打印”看起来可疑,因为打印不等待提示才返回。最好始终设置Net::Telnet对象的“提示”字段,然后使用->cmd,它将在返回前等待提示。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10389195

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档