use strict; use warnings; use Data::Dumper; use Net::OpenSSH; use Sys::SigAction qw( set_sig_handler sig_alarm timeout_call); use File::Path 'rmtree'; #$Net::OpenSSH::debug = -1; my $sshuser="user"; my $sshpwd="pwd"; my $sshtimeout = 90; # sec for timeout my $workertimeout = 120; my @rawout=(); my $device = $ARGV[0]; my $remoteCmd = $ARGV[1]; my $error; my $ssh; my $path = "./Y.ssh.$$"; my @sshcmds= split(';', $remoteCmd); foreach my $sshcmd (@sshcmds) { rmtree([ $path ]); $ssh = Net::OpenSSH->new( $device, user => $sshuser, passwd => $sshpwd, ctl_dir => $path, master_opts => [-o => "StrictHostKeyChecking=no", -o => "UserKnownHostsFile=/dev/null"], timeout => $sshtimeout, kill_ssh_on_timeout => 1, strict_mode => 0, master_stderr_discard => 1 # to get rid of login screen ); if ($ssh->error) { $error = $ssh->error; chomp($error); print STDOUT "ERROR-1: " . $error . "\n"; rmtree([ $path ]); exit 1; }; if (timeout_call($workertimeout, sub{ my @cmdout = $ssh->capture({timeout => $sshtimeout, stdin_data => "\n"}, $sshcmd."\n"); if ($ssh->error) { $error = $ssh->error; chomp($error); print STDOUT "ERROR-2: " . $error . "\n"; rmtree([ $path ]); exit 2; }; push @rawout, @cmdout; } )) { # time out action print STDOUT "ERROR-3: SSH cancled by thread after $workertimeout secs\n"; rmtree([ $path ]); exit 3; }; if ($ssh->error) { $error = $ssh->error; chomp($error); print STDOUT "ERROR-4: SSH: " . $error ."\n"; rmtree([ $path ]); exit 4; }; $ssh->master_exited; } rmtree([ $path ]); foreach (@rawout) { print STDOUT $_; } exit 0;