通过perl的open2执行时,telnet命令输出未完全打印

时间:2016-10-17 11:03:56

标签: perl telnet

我是perl的新手。

我的目标:执行telnet命令并捕获完整输出

我的代码:

use IPC::Open2;

open2(\*RDR, \*WTR, "telnet host_name 8000 2>&1") or die ("could not contact host_name");

print WTR "$command\n";

print WTR "quit\n";
foreach my $line (<RDR>)
   {
      print $line."\n";
   }
close RDR;

问题:通过putty执行telnet命令时,会打印超过12行的输出。但是通过这个perl脚本只打印了3行

决议尝试: 我试过Expect,Net :: Telnet,IO :: Pty。但由于安全原因,这些模块未安装在我的刀片服务器中。

问题:那么,如果不使用任何这些有用的魔术模块,如何使用perl获得任何telnet命令的完整输出?输出缓冲区中的字符数有限制吗?

1 个答案:

答案 0 :(得分:2)

你没有对你的$command说些什么,但这对我有用。

use warnings 'all';
use strict;

use IPC::Open2;

my $host = 'google.com';

my $pid = open2(\*RDR, \*WTR, "telnet $host 80 2>&1") 
    or die "Can't contact $host: $!";

print WTR "GET\n";    
print WTR "quit\n";

while (my $line = <RDR>)
{
    print $line if $. <= 10;      # print only first 10 lines
}   
close RDR;

waitpid($pid, 0);
my $child_exit_status = $? >> 8;  # check how it went

这将打印整个页面(没有if ...)。为方便起见,打印限制为10行。

请仔细阅读文档IPC::Open2,因为所有这些都涉及到。

  

open2()返回子进程的进程ID。 [...]
    退出后,open2()不会等待并收获子进程。 [...]
      整个事件是非常危险的,因为你可能永远阻止。 [...]

另见IPC::Open3。如果可能的话,一个备受好评的模块是IPC::Run。同样优秀的是Tiny::Capture,在this recent post中使用它的问题非常类似。两者都是众所周知的,所以也许你的管理员可以接受它们。

我建议切换到词法文件句柄

my $pid = open2 my $read_fh, my $write_fh, "telnet $host 80 2>&1" 
    or die "Can't contact $host: $!";

并在整个过程中更改RDRWTR

我不知道Windows环境如何影响上述情况。这些模块会给人一些信心,但我不确定open2票价如何。另一个可能的罪魁祸首可能是缓冲,即使我不知道它在你的代码中会是怎样的。以防万一,您可以尝试

use IO::Handle;
STDERR->autoflush(1);
STDOUT->autoflush(1);

默认情况下会加载IO::Handle,我认为是v5.16。

还会看到关于此in perlfaq5的讨论,并提供进一步阅读的链接。

但是,如果确实存在缓冲问题,则很可能在另一端,如果没有模块,可能不容易解决。引用Camel

  

如上所述,IO::PtyExpect模块提供了伪tty设备,为您提供行缓冲,而无需修改管道末端的程序。