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: $!"; }