use IO::Select;
# fire off all the ssh requests
my %ssh_handles = ();
foreach my $host ( keys %hosts ) {
open my $ssh, '-|', "ssh $host 'echo $host'"
or die "Can't ssh to $host: $!";
$ssh_handles{$host} = $ssh;
}
# prepare to wait for them to finish
my $select = IO::Select->new();
$select->add( $_ ) for values %ssh_handles;
# wait until they're all done
my @ready;
while ( scalar @ready < scalar keys %ssh_handles ) {
@ready = $select->can_read();
}
# @ready should be the same as values %ssh_handles
foreach my $host ( keys %hosts ) {
my $ssh = $ssh_handles{$host};
my $ssh_result = do { local $/; <$ssh> };
print "$host said $ssh_result\n";
close $ssh or warn "Can't close $host ssh: $!";
}
With some added complexity, you can tune how many of these you run at once (instead of all of them), you can output results as they come back (instead of only when they're all done). If you want, you can use select instead of IO::Select, but I find the module easier.
Update: Fixed a typo. Thanks cmv! |