免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 42283 | 回复: 8
打印 上一主题 下一主题

关于perl telnet的prompt问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-07-31 15:04 |只看该作者 |倒序浏览
本帖最后由 zljjg2000 于 2016-07-31 15:04 编辑

程序如下:
open(FILE,"<E:/设备中心/1-包机/2015-专线提取/$ARGV[0]")||die"cannot open the file: $!\n";
#程序执行时,手工输入sr.pl source-ne40e.txt;
#source-ne40e里存放着所有ne40e的ip地址清单;

use Net::Telnet();
#引入Net::Telnet模块
$username="xxx";
$passwd="xxx";
while (<FILE>)
{
   $line1=$_;
   @list1=split(/\s+/,$line1);
   $host=$list1[0];
   $tishifu=$list1[1];
   
#$host取出ne40e的ip地址
   unlink  "dest-ne40e.txt";
#删除程序运行前已经存在的老的dest-ne40e.txt;


$t = new Net::Telnet (Timeout => 10,Prompt => $tishifu);
$t->open($host);
$t->login($username, $passwd);
sleep(3);
$t->cmd("sys");
sleep(3);
$t->cmd("user-interface vty 0 4");
sleep(3);
$t->cmd("screen-length 0");
sleep(3);
@lines = $t->cmd("dis version");
print @lines;

}
close FILE;
close EP;
close FP;
#关闭文件句柄

注:source-ne40e.txt文件里存放内容如下:
192.168.1.1 <NE40E-X16-S1>
192.168.1.2 <NE40E-X8-S1>

运行程序sr.pl source-ne40e.txt, 结果报错如下:

bad Prompt argument "<NE40E-X16-S1>": missing opening delimiter of matc
h operator at E:\设备中心\1-包机\2015-专线提取\sr.pl line 23

将$tisihfu直接写成'<NE40E-X16-S1>',也不行,求教高手。

论坛徽章:
42
19周年集字徽章-周
日期:2019-10-14 14:35:31平安夜徽章
日期:2015-12-26 00:06:30数据库技术版块每日发帖之星
日期:2015-12-01 06:20:002015亚冠之首尔
日期:2015-11-04 22:25:43IT运维版块每日发帖之星
日期:2015-08-17 06:20:00寅虎
日期:2014-06-04 16:25:27狮子座
日期:2014-05-12 11:00:00辰龙
日期:2013-12-20 17:07:19射手座
日期:2013-10-24 21:01:23CU十二周年纪念徽章
日期:2013-10-24 15:41:34IT运维版块每日发帖之星
日期:2016-01-27 06:20:0015-16赛季CBA联赛之新疆
日期:2016-06-07 14:10:01
2 [报告]
发表于 2016-07-31 20:54 |只看该作者
本帖最后由 laputa73 于 2016-07-31 20:55 编辑

不能用cmd
要用print和waitfor
cmd的prompt是写死的

论坛徽章:
0
3 [报告]
发表于 2016-08-01 10:38 |只看该作者
需要对 '/' 转义。

"\/"

论坛徽章:
0
4 [报告]
发表于 2016-08-02 17:11 |只看该作者
本帖最后由 zljjg2000 于 2016-08-02 17:13 编辑

谢谢楼上们的解答,现在程序修改后,报错变成了下面的信息:
程序修改后:
open(FILE,"<E:/设备中心/1-包机/2015-专线提取/$ARGV[0]")||die"cannot open the file: $!\n";
#程序执行时,手工输入sr.pl source-ne40e.txt;
#source-ne40e里存放着所有ne40e的ip地址清单;

open(EP,">>E:/设备中心/1-包机/2015-专线提取/result");
#将执行结果存放到result文件中

use Net::Telnet();
#引入Net::Telnet模块
$username="xxx";
$passwd="xxx";
while (<FILE>)
{
    $line1=$_;
    @list1=split(/\s+/,$line1);
    $host=$list1[0];
    $tishifu="/".$list1[1]."/";   ------------已将$tishifu修改了
   
#$host取出ne40e的ip地址
   unlink  "dest-ne40e.txt";
#删除程序运行前已经存在的老的dest-ne40e.txt;


my $t = new Net::Telnet ('Host'=>$host,Timeout => 10,Prompt => $tishifu,Output_Log=>"E:/设备中心/1-包机/2015-专线提取/Output_log.log");
$t->waitfor('Match'=>"/Username:/");
$t->print($username);
$t->waitfor('Match'=>"/ord:/");
$t->print($passwd);
$t->waitfor('Match'=>"/\>/");
$t->print("sys");
sleep(3);
$t->print("user-interface vty 0 4");
sleep(3);
$t->print("screen-length 0");
sleep(3);
my @lines=$t->cmd(String=>"disp arp interface Eth-Trunk 3.410");      --------第50行
print EP @lines;
print @lines;
$t->print("exit");
$t->print("screen-length 24");
$t->print("exit");
$t->close(); }
close FILE;
close EP;
close FP;
#关闭文件句柄

注:source-ne40e.txt文件里存放内容如下:
192.168.1.1 <NE40E-X16-S1>
192.168.1.2 <NE40E-X8-S1>

运行程序sr.pl source-ne40e.txt, 结果报错如下:

command timed-out at E:\设备中心\1-包机\2015-专线提取\sr.pl line 50

这是怎么回事啊?
若要将cmd换成print,那程序能通过,但是就无法将disp arp interface Eth-Trunk 3.410的命令结果保存下来了。

注:source-ne40e.txt文件里存放内容如下:
192.168.1.1 <NE40E-X16-S1>
192.168.1.2 <NE40E-X8-S1>

论坛徽章:
42
19周年集字徽章-周
日期:2019-10-14 14:35:31平安夜徽章
日期:2015-12-26 00:06:30数据库技术版块每日发帖之星
日期:2015-12-01 06:20:002015亚冠之首尔
日期:2015-11-04 22:25:43IT运维版块每日发帖之星
日期:2015-08-17 06:20:00寅虎
日期:2014-06-04 16:25:27狮子座
日期:2014-05-12 11:00:00辰龙
日期:2013-12-20 17:07:19射手座
日期:2013-10-24 21:01:23CU十二周年纪念徽章
日期:2013-10-24 15:41:34IT运维版块每日发帖之星
日期:2016-01-27 06:20:0015-16赛季CBA联赛之新疆
日期:2016-06-07 14:10:01
5 [报告]
发表于 2016-08-02 17:35 |只看该作者
本帖最后由 laputa73 于 2016-08-02 17:48 编辑

善用waitfor的返回
($prematch, $match)=$sess->waitfor(Match => $str, Timeout => $to);

忘掉cmd和login吧,那是给主机专用的。

论坛徽章:
42
19周年集字徽章-周
日期:2019-10-14 14:35:31平安夜徽章
日期:2015-12-26 00:06:30数据库技术版块每日发帖之星
日期:2015-12-01 06:20:002015亚冠之首尔
日期:2015-11-04 22:25:43IT运维版块每日发帖之星
日期:2015-08-17 06:20:00寅虎
日期:2014-06-04 16:25:27狮子座
日期:2014-05-12 11:00:00辰龙
日期:2013-12-20 17:07:19射手座
日期:2013-10-24 21:01:23CU十二周年纪念徽章
日期:2013-10-24 15:41:34IT运维版块每日发帖之星
日期:2016-01-27 06:20:0015-16赛季CBA联赛之新疆
日期:2016-06-07 14:10:01
6 [报告]
发表于 2016-08-03 08:45 |只看该作者
简单来说,每一次print,都必需跟至少一个waitfor(其实就是expect),来保证输出缓冲区被读取
如果用数组来取,就是被存到prematch部分
如果用标量来取,就被丢弃了
如果你不取,那么缓冲区内容保留,和下一次的print内容叠加
再次waitfor时,实际取到的是前一次print的结果

你的print passwd后面没有waitfor,造成了错位。
print+sleep那是tcl的笨做法。

你可以看到因为你设的str是NE40E-X16-S1,所以打印的信息没有包含后面的]
这个就是prompt的选取问题,要保证match到的最好是最后一个字符,否则缓冲区就可能没被取完
注意。普通模式的结尾字符是>,sys模式的结尾字符是]

论坛徽章:
0
7 [报告]
发表于 2016-08-03 17:46 |只看该作者
谢谢laputa73大侠,我明白了。
感觉print和waitfor还挺脆弱的。。。
不过net::telnet对于网络维护人员,这方面的工具还挺好的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP