我正在尝试创建一个ping(使用linux系统ping)的perl模块 数百台主机,从每台主机的stdout获取ping数据(如数据包丢失,传输的数据包数量和接收的数量等)。 我使用了AnyEvent :: Util fork_call,但是因为它没有收集stdout而被卡住了。 我创建了一个小脚本来演示我正在尝试做的事情:
#!/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;
我哪里出错?
答案 0 :(得分:3)
您需要等待ping才能完成($cv->recv;
)才能打印输出。
my $ping_data = fork_ping();
$cv->recv;
p $ping_data;
(您也可以将$cv->recv;
放在fork_ping
内。)
答案 1 :(得分:1)
如果您也可以使用Perl解决问题,请不要调用外部程序。它将使您的应用程序依赖于ping命令的可用性,它的API(CLI参数名称,顺序,格式)及其可能更改的输出格式。
我多年来成功使用POE :: Component :: Client :: Ping来监控数千个网络设备。