I was assigned a very simple task – write a script that opens SSH connection to a remote server, waits 30 seconds and closes the connection. About 5 minutes of work on Linux.
On windows it took an entire day.
First attempt: Using MKS32’s KSH.
d:/sitescope/tools/plink sitescope@testdb -pw pass -m d:/sshTest_cmd2;
SSH_PID=$!
echo $SSH_PID
(sleep 30 ; kill $SSH_PID);
Problem: The ssh process executed within a subshell, and I only got the PID for the subshell. Killing the subshell did not kill the SSH process.
Second attempt: Using Perl’s fork, exec and wait.
$pid = fork;
if($pid == 0) {
exec("d:/sitescope/tools/plink sitescope@testdb -pw pass -m d:/sshTest_cmd2");
}elsif ($pid > 0) {
sleep 30;
kill(9,$pid);
} else {
print "fork failed";
};
Problem: Under windows, fork is not a real fork. It creates a “pseudo process” (AKA thread), and $PID is a negative number. Not a real process ID. After the “exec”, the child thread will become a real process with PID, but again, I’ll not have the PID.
Third attempt: Perl has a WIN32 package, which includes a process object, allowing me to create a process, wait for it, and kill it.
use Win32;
use Win32::Process;
use Win32::Process (STILL_ACTIVE);
sub ErrorReport{
print Win32::FormatMessage( Win32::GetLastError() );
}
$params = "plink sitescope\@$ARGV[0] -pw $ARGV[1] -m D:\\sshTest_cmd";
print "$params \n";
Win32::Process::Create($ProcessObj,"D:\\SiteScope\\tools\\plink.exe",$params,0,
NORMAL_PRIORITY_CLASS,".")|| die ErrorReport();
$PID = $ProcessObj->GetProcessID();
print "$PID \n";
$ProcessObj->Wait(30000);
$ProcessObj->GetExitCode($exitcode);
print "exit code is: $exitcode \n";
if ($exitcode == 0)
{
print "exiting normally \n";
exit 0;
} elsif ($exitcode == STILL_ACTIVE)
{
print "killing ssh \n";
$ProcessObj->Kill(59);
exit 59;
} else
{
print "ssh exited abnormally \n";
exit $exitcode;
}
Finally something works
Subscribe 