http://www.perlmonks.org?node_id=1008645

Boldra has asked for the wisdom of the Perl Monks concerning the following question:

This question has a lot of non-Perl parts to it, but I'm running a Perl script on a remote machine, so it would be nice to solve the problem in Perl.

I'm trying to start a detached process on a remote server. The following test shows my problem:

ssh user@host 'perl-E "fork or exec q{sleep 20}"'
or equivalently:
ssh user@host 'perl-E "$|++; \$SIG{CHLD}=q{IGNORE}; say q{START}; if( +fork){exit}else{close STDIN; close STDOUT; close STDERR; exec q{sleep + 20}}"'

If the remote machine is linux, the first version waits for 20 seconds, and the second version exits immediately. But most of my machines are windows machines running cygwin opensshd, and the connection stays open until the child is finished in both versions. I can't do the detach on my side of the connection because I need to conserve network ports.

One option has been to use sysinternals psexec -d to launch the detached process, but this frequently fails silently, particularly shortly after booting the machine. It does at least close the ssh connection immediately. Since I'm running a Perl script on the remote machine anyway, it would make sense to do this completely in Perl. My ssh calls are actually made via Net::OpenSSH, but the test shows that this is not causing the problem.

(I tried posting this on G+ yesterday to see if the perl "community" there could help: https://plus.google.com/#communities/105035827361077606043. So far nothing )





- Boldra

Replies are listed 'Best First'.
Re: cygwin opensshd: how to detach remotely with fork/exec?
by zentara (Archbishop) on Dec 13, 2012 at 17:30 UTC
    Since no one has answered you yet, I'll throw this out. To exec a program in the background with SSH2 on linux, we use this to close off the file numbers of the process being backgrounded. I think it is important to do that, just as if it were a daemon.
    my $chan = $ssh2->channel(); $chan->blocking(1); $chan->exec("nohup /home/zentara/perlplay/net/zzsleep > foo.out 2> foo +.err < /dev/null &"); $chan->send_eof;
    I know the SSH2 libs are not what you are using, but it might help for you to see a correctly setup nohup string.

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh

      Many thanks for your ideas Zentara.

      Do you know if there is a difference between the way you are redirecting the standard filehandles and the way I do it in my example with close? I've tried both now, and neither seems to solve the detach problem with the cygwin sshd. nohup also doesn't seem to have any meaning to cygwin - but I'm not forcing the connection closed. Maybe I can do that with an alarm?

      At the moment I'm working with psexec again. I'm repeatedly sending simple psexec commands until one works, and then doing the important command. This seems reasonably reliable, if slow.



      - Boldra