I found some time and I put together 80% - 90% of the work of your request.
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use Net::OpenSSH::Parallel;
#$Net::OpenSSH::Parallel::debug = -1;
my %hosts = ( localhost => { host => "localhost",
user => "user",
port => "22", # default 22
psw => "psw", # use only if no ssh keys
key => "/home/user/.ssh/id_rsa", # linux default di
+r
dir => "/home/user/LOG",
log => "output1.txt",
error => "error1.txt", },
localhost_2 => { host => "127.0.0.1",
user => "user",
port => "22",
psw => "psw",
key => "/home/user/.ssh/id_rsa",
dir => "/home/user/LOG",
log => "output2.txt",
error => "error2.txt", },
);
my @commands = ( 'echo %HOST%' , 'df -h' ); # Remove first command if
+unecessary
# is the maximun number of remote commands that can be running concurr
+ently.
my $maximum_workers = @commands;
# it is recomended that maximum_connections >= 2 * maximum_workers
my $maximum_connections = 2 * $maximum_workers;
my $maximum_reconnections = 0;
my %opts = ( workers => $maximum_workers,
connections => $maximum_connections,
reconnections => $maximum_reconnections
);
my $pssh = Net::OpenSSH::Parallel->new( %opts );
my $num = 0;
my @stdout_fh = ();
my @stderr_fh = ();
foreach my $label (keys %hosts) {
mkdir $hosts{$label}{dir} unless -d $hosts{$label}{dir};
# Open file and append
open($stdout_fh[$num], '>', $hosts{$label}{dir}."/".$hosts{$label}
+{log})
or die "Could not open file '$hosts{$label}{dir}/$hosts{$label}{lo
+g}' $!";
# Open file and append write
open($stderr_fh[$num], '>>', $hosts{$label}{dir}."/".$hosts{$label
+}{error})
or die "Could not open file '$hosts{$label}{dir}/$hosts{$label}{er
+ror}' $!";
$pssh->add_host( $hosts{$label}{host},
user => $hosts{$label}{user},
port => $hosts{$label}{port},
#password => $hosts{$label}{psw},
default_stdout_fh => $stdout_fh[$num],
default_stderr_fh => $stderr_fh[$num],
key_path => $hosts{$label}{key},
);
$num++;
}
# Assigning all commands to all hosts
$pssh->push('*', command => $_ ) for @commands;
$pssh->run;
closeFH ( @stdout_fh , @stderr_fh );
print Dumper fileProcessing();
sub closeFH {
foreach my $fh (@_) { close $fh or die "Error closing $!\n"; }
}
sub fileProcessing {
my $ref_hash = {};
foreach my $label (keys %hosts ) {
# Open file to read
open(my $fh, '<', $hosts{$label}{dir}."/".$hosts{$label}{log})
or die "Could not open file '$hosts{$label}{dir}/$hosts{$label
+}{log}' $!";
chomp( my @data = <$fh> );
close $fh
or die "Could not close file '".$hosts{$label}{dir}."/".$hosts
+{$label}{log}."' $!";;
$$ref_hash{$label} = \@data;
}
return $ref_hash;
}
__END__
$VAR1 = {
'localhost' => [
'localhost',
'Filesystem Size Used Av
+ail Use% Mounted on',
'udev 7.8G 0 7
+.8G 0% /dev',
'tmpfs 1.6G 9.7M 1
+.6G 1% /run',
'/dev/mapper/ubuntu--vg-root 218G 15G 1
+93G 8% /',
'tmpfs 7.8G 86M 7
+.8G 2% /dev/shm',
'tmpfs 5.0M 4.0K 5
+.0M 1% /run/lock',
'tmpfs 7.8G 0 7
+.8G 0% /sys/fs/cgroup',
'/dev/sda2 473M 125M 3
+24M 28% /boot',
'/dev/sda1 511M 3.6M 5
+08M 1% /boot/efi',
'cgmfs 100K 0 1
+00K 0% /run/cgmanager/fs',
'tmpfs 1.6G 68K 1
+.6G 1% /run/user/1000'
],
'localhost_2' => [
'127.0.0.1',
'Filesystem Size Used
+Avail Use% Mounted on',
'udev 7.8G 0
+ 7.8G 0% /dev',
'tmpfs 1.6G 9.7M
+ 1.6G 1% /run',
'/dev/mapper/ubuntu--vg-root 218G 15G
+ 193G 8% /',
'tmpfs 7.8G 86M
+ 7.8G 2% /dev/shm',
'tmpfs 5.0M 4.0K
+ 5.0M 1% /run/lock',
'tmpfs 7.8G 0
+ 7.8G 0% /sys/fs/cgroup',
'/dev/sda2 473M 125M
+ 324M 28% /boot',
'/dev/sda1 511M 3.6M
+ 508M 1% /boot/efi',
'cgmfs 100K 0
+ 100K 0% /run/cgmanager/fs',
'tmpfs 1.6G 68K
+ 1.6G 1% /run/user/1000'
]
};
Next step is to create a function (sub) to open and process the files that you have created, I will leave this part for you.
Hope this helps...