I connect to the remote host and running a command that does not exit (tail -f logfile)
I register a handler and write the output to a log file. This works fine. But I want to press Control + C on the main program, and it should stop the command on the remote machine and close the ssh connection gracefully
So, I register a signal handler for SIGINT
You need the code that I need to put in the subroutine
Below code is inside a function that is called from a forked child
#!/ats/bin/perl use Net::SSH::Perl; use File::Path; use Text::CSV_XS; chomp ($progName = `basename $0`); if (@ARGV != 1 ) { print "usage: perl $progName <tc_id>\n"; exit; } $tc_id = shift; $file = "config.prop"; $log_dir = "logs/"; #$SIG{INT}=\&close_write; sub close_write { #-- write it to file print "\nInside END block\n"; #open FH, ">$log_file"; #print $log_file; #print FH @out; #$thr->kill('INT'); #close $ssh->sock; #undef $ssh; exit 1; } # Read the configuration file and populate the Hash $index = 0; my $csv = Text::CSV_XS->new ({ binary => 1, eol => $/ }); open my $io, "<", $file or die "$file: $!"; while (my $row = $csv->getline ($io)) { next if (${$row}[0] =~ m/^#/); #Ignore comments next if (${$row}[0] =~ m/^\s*$/); #Ignore blank lines ($logHashArray->[$index]->{host}, $logHashArray->[$index]->{user}, $logHashArray->[$index]->{pass}, $logHashArray->[$index]->{cmd}, $logHashArray->[$index]->{log_file}) = @$row; $index++; } # Append "/" at the end of the directory if it does not exist unless ($log_dir =~ m/\/$/) { $log_dir = $log_dir . "/"; print "LogDir: $log_dir\n"; } # Check if the log directory exists, if not, create it if (-e $log_dir) { unless (-d $log_dir) { die "File exists but is not directory"; } } else { # don't forget to check mkdir failure print "Directory $log_dir does not exist... Creating it\n"; mkpath($log_dir, 0777) or die "Can't make directory: $!"; } foreach $logHash (@{$logHashArray}){ #print "LogHash Index $logHash\n"; $logHash->{log_file} = $tc_id . "_" . $logHash->{host} . "_" .$logHash->{log_file}; $logHash->{cmd} = $logHash->{cmd} . " | tee /tmp/" . $logHash->{log_file}; $logHash->{log_dir} = $log_dir; #$logHash->{thr}=threads->new(\&connect_get_logs, $logHash); $logHash->{pid} = fork(); if ($logHash->{pid}){ # Parent push(@childs, $logHash->{pid}); } elsif ($pid == 0){ # Child connect_get_logs($logHash); } else { die "couldn't fork: $!\n"; } while (($key, $value) = each(%{$logHash})){ print $key."=>".$value."\n"; } } #$SIG{INT}=\&close_write; #$thr=threads->new(\&connect_get_logs, $logHash); foreach (@childs) { waitpid($_, 0); } #print "Waiting..."; #while(1) {sleep 1;} #$thr->join; sub connect_get_logs{ $SIG{INT}= sub { print "Inside INT block\n"; ### Need proper code here close $ssh->sock; undef $ssh; }; my $logHash = shift; while (($key, $value) = each(%{$logHash})){ print $key."=>".$value."\n"; } my $stdout; my $stderr; my $exit; #-- setup a new connection print "Logging in to $logHash->{host}..."; my $ssh = Net::SSH::Perl->new($logHash->{host}, debug => 0, protocol => '2', options => ["PasswordAuthentication yes", "BatchMode yes", "PubkeyAuthenticaion no", "RhostsAuthentication no", "RhostsRSAAuthentication no", "RSAAuthentication no", "DSAAuthentication no"]); #-- authenticate $ssh->login($logHash->{user}, $logHash->{pass}); print "Logged In\n"; #-- Create or Overwrite the log files open LOG_FILE, ">", "$logHash->{log_dir}$logHash->{log_file}" or die $!; #-- register a handler $ssh->register_handler("stdout", sub { my($channel, $buffer) = @_; $str = $buffer->bytes; #push @out, $str; print LOG_FILE $str; #print $str; }); #$SIG{INT}=\&close_write; #-- execute the command ($stdout, $stderr, $exit) = $ssh->cmd($logHash->{cmd}); print "Error: $stderr"; }
create config.prop file in csv format
host / ip, username, password, command (tail -F / full / path / to / logfile), file name to save as