Perl通过Telnet远程执行命令

十一月 3rd, 2009 | 964 次阅读
Tags: 技术 perl telnet Posted in 技术杂项 :-)说点什么吧

      Perl脚本在远程的机器上执行命令的方法有几种,例如直接通过system函数调用rsh、通过NET::SSH:Perl模块通过ssh登录远程机器来执行或者是通过NET::Telnet模块通过telnet登录到远程机器上执行。笔者比较喜欢Telnet登录这种方法,因为它比rsh强大,却又足够灵活,既能达到SSH的使用水平,同时又足够轻巧(只需要一个模块:Telnet.pm就够了)。

      NET::Telnet模块的详细使用指南可以参考该模块的CPAN官方文档。我们在这里只简单地结合代码来介绍其使用方法。

01 use Net::Telnet;
02
03 my $t = new Net::Telnet(Timeout => 30,Prompt => '/[\$#>]/', Errmode => "return");
04 $t -> max_buffer_length("10485760");
05
06 my $ok = $t->open("192.168.1.12");
07
08 unless($ok eq 1){
09          my $errmsg = $t->errmsg();
10          print STDERR "$errmsg\n";
11 }
12
13 $ok = $t->login($username,$passwd);
14
15 unless($ok eq 1){
16          my $errmsg = $t->errmsg();
17          print STDERR "$errmsg\n";
18 }
19
20 my @temp = $t->cmd(String => "PS1=\"@@@\"",Prompt => '/@@@/'); #change the Prompt temporality
21 $t->buffer_empty;
22
23 while(my $cmd=<>){         #Exec each cmd in the cmds list
24         my @results = $t->cmd(String => $2, Prompt  => '/@@@/');
25         print $results[-1];
26         $t->buffer_empty;
27 }

 

     现在我们来对以上的代码进行解释,其中第3行就是建立一个telnet对象,其构造参数用于指定给对象所建立的连接将用到的参数,在这里我们指定了超时时间Timeout、错误模式Errmode,以及远程机器上的命令提示符Prompt。Timeout指的是Telnet登录或者执行命令的超时时限,我们这里赋予了30,也就是说如果远程机器在30秒内没有回显出命令提示符,telnet的连接就等于超时断开;Errmode有两种值:die和return,默认是die,如果选择的是die,则该对象所执行的方法出了错误,整个perl脚本就die掉并会把错误信息输出到标准输出中,如果选择的是return,则在出错的时候会直接返回一个undefined的标量值或一个空向量,并将错误信息放在对象中,可以通过对象的errmsg()方法来获取;Prompt这个参数很重要,因为NET::Telnet模块是通过命令提示符来判断登录成功与否以及命令是否执行结束,通过正则表达式来设定,我们这里设定为 "/[\$#>]/”,也就是说远程机器的命令提示符包含了’$’、’#’、’>’这三种字符之一,如果设定的命令提示符不与该正则表达式match,那么在登录或者执行命令的时候,会因为等不到命令提示符而超时。

      在第4行,我们更改了这个Telnet对象的缓冲区,单位是K字节,该缓冲区是用来存放远程机器上的输出结果的,这里的10485760也就是10MB(绝对够用的啦)。

      第6行,通过传入远程机器的IP地址调用Telnet对象的open方法来连接远程机器,如果连接成功,则返回值等于1。在第13行,通过用户名和密码登录到远程机器的系统中。

     在第20行,我们通过Telnet对象的cmd方法将要在远程机器上运行的命令传递到远程机器上面去。这里我们通过向远程机器传递PS1=“@@@”这条命令临时地改变了远程机器的命令提示符,之所以这样做,是因为Telnet模块是根据命令提示符来判断传上去的命令是否执行完毕的,如果我们传上去的命令中包含了可以与Telnet对象的Prompt参数match的字符串,那么cmd方法会直接返回(好囧啊)。于是乎,我们在这里临时改变了其命令提示符为@@@(应该不会有一个变态的命令会用到这种字符串吧)。由于命令提示符改变了,因此我们在cmd方法中还要传入Prompt参数@@@,否则下场就如同Telnet对象的Prompt属性没设对…。

     第21行,清空Telnet对象的缓冲区,否则有可能出现命令输出错位,这个读者可以自己试一下是怎样的效果。

      23行至27行,就是重复地读取命令,再将命令放到远程机器上执行,之后将结果输出。记得执行这些命令的时候要使用新的命令提示符作为分割点哦,也不要忘了在获取返回结果之后清空缓冲区哈。

Relate Posts:// 相关文章

日子就是这么过的»
«Nike The Human Race 10K

“Perl通过Telnet远程执行命令” 共有2条留言

我要留言

9+6=