Perl通过Telnet远程执行命令
Perl脚本在远程的机器上执行命令的方法有几种,例如直接通过system函数调用rsh、通过NET::SSH:Perl模块通过ssh登录远程机器来执行或者是通过NET::Telnet模块通过telnet登录到远程机器上执行。笔者比较喜欢Telnet登录这种方法,因为它比rsh强大,却又足够灵活,既能达到SSH的使用水平,同时又足够轻巧(只需要一个模块:Telnet.pm就够了)。
NET::Telnet模块的详细使用指南可以参考该模块的CPAN官方文档。我们在这里只简单地结合代码来介绍其使用方法。
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行,就是重复地读取命令,再将命令放到远程机器上执行,之后将结果输出。记得执行这些命令的时候要使用新的命令提示符作为分割点哦,也不要忘了在获取返回结果之后清空缓冲区哈。
soma chico's nfkneq diamond state federal credit union 1747 get prozac :-[[ offline multi line slots wtphk wii slot mod tqujaj
lipitor and swallowing problems joh adobe creative suite cs2 professional combine jvuuqm quark selber machen abdsv hold em poker software 747 gemb credit cards 4068 delaware meridia legal 2121