2013-07-22 24 views
3

我试图创建一个perl模块,ping(使用linux系统ping) 到数百个主机,并获得ping的数据(如丢包,多少数据包传输和多少收到等)从每个主机的标准输出。 我用AnyEvent :: Util fork_call,但因为它不收集标准输出而卡住了。 我创建了一个小脚本,演示了我想要做的事:AnyEvent fork_call和ping

#!/usr/bin/perl 
use strict; 
use warnings; 

use AnyEvent; 
use AnyEvent::Util 'fork_call'; 
use DDP; 

my $cv = AE::cv; 

my @hosts = ('google.com', 'xkcd.com', 'pastebin.com', 'youtube.com'); 

sub fork_ping { 
    my $interval  = 0.2; 
    my $source_address = '1.1.1.1'; 
    my $number_of_pings = 5; 
    my $timeout   = 5; 

    my %ret_val; 

    foreach my $host (@hosts) { 
     $cv->begin; 
     fork_call { 
      my $stdout = `ping -c $number_of_pings -I $source_address -i $interval -W $timeout $host 2>&1`; 
      return $stdout; 
     } sub { 
      $ret_val{$host} = shift; 
      $cv->end; 
     }; 
    } 

    return \%ret_val; 
} 


my $timer = AE::timer 0, 5, sub { 

    my $ping_data = fork_ping(); 
    p $ping_data; 
}; 

$cv->recv; 

我在哪里有错?

回答

3

您需要等待ping才能完成($cv->recv;),然后才能打印输出。

my $ping_data = fork_ping(); 
$cv->recv; 
p $ping_data; 

(你也可以放置$cv->recv;fork_ping内。)

1

不要调用外部程序,如果你可以用Perl解决它。它将使您的应用程序依赖于ping命令的可用性,它的API(CLI参数名称,顺序,格式)及其可能更改的输出格式。

我使用POE :: Component :: Client :: Ping成功数年来监测我们的数千个网络设备。