3

我正在尝试创建一个 perl 模块,它可以 ping(使用 linux 系统 ping)到数百台主机,并从标准输出获取 ping 的数据(例如丢包以及传输的数据包数量以及接收的数据包数量等)每个主机的。我使用了 AnyEvent::Util fork_call,但我被卡住了,因为它没有收集标准输出。我创建了一个小脚本来演示我正在尝试做的事情:

#!/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;

我哪里错了?

4

2 回答 2

3

您需要等待 ping 完成 ( $cv->recv;) 才能打印它们的输出。

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

(你也可以把$cv->recv;里面放fork_ping。)

于 2013-07-22T15:51:02.193 回答
1

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

多年来,我成功地使用 POE::Component::Client::Ping 来监控我们成千上万的网络设备。

于 2013-07-28T09:25:54.140 回答