2013-07-22 3 views
3

Я пытаюсь создать модуль perl, который пингует (используя систему linux ping) сотням хостов и получает данные из ping (например, потери пакетов и сколько переданных пакетов и сколько полученные и т. д.) со стороны каждого хоста. Я использовал AnyEvent :: Util fork_call, но я застрял, поскольку он не собирает stdout. Я создал небольшой скрипт, который демонстрирует, что я пытаюсь сделать: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

Прежде чем вы сможете распечатать свой результат, вам нужно подождать, пока пинги не закончатся ($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 с годами для мониторинга тысяч наших сетевых устройств.