1

The task is to use python to run a remote process in background and immediately close the ssh session.

I have a remote script name 'start' under server:PATH/, the start script does nothing but lunch a long-live background program. 'start' script which has one line:

nohup PATH/Xprogram &

When I use python subprocess module to call my remote 'start' script, it does start OK. But the issue is: it seems the SSH connection is persist, meaning I am getting stdout from the remote Xprogram (since it is a long live program which has output to stdout). Does this indicating ssh connection is still there ?

All I need is call the start script without blocking and forget about it (leave the long-live program running, close ssh, release resources).

my python function call looks like this:

ret = subprocess.Popen(["ssh", "xxx@servername", "PATH/start"])

if I use ret.terminate() after the command, it then will kill the long-live program too. I have also tried spur module. basically the same thing.

=====update====

@Dunes' answer solves the problem. Based on his answer, I did more digging and found this link very helpful. My understanding of this is: basically, if any file descriptor is still held by your process (e.g. stdout held by my XProgram), then SSH session won't exit. However redirect stdout/stderr to NULL effectively close those file descriptor and let SSH session exit normally.

solution

ret = subprocess.Popen(["ssh", "xxx@servername", "PATH/start >dev/null 2>&1"])
Community
  • 1
  • 1
hefeicoder
  • 123
  • 1
  • 7
  • Is http://stackoverflow.com/questions/13592219/launch-a-totally-independent-process-from-python relevant? Or perhaps http://stackoverflow.com/questions/29661527/how-to-spawn-detached-background-process-on-linux-in-either-bash-or-python ? – pjvandehaar Feb 10 '16 at 22:59
  • Possible duplicate of [Run a persistent process via ssh](http://stackoverflow.com/questions/9237385/run-a-persistent-process-via-ssh) – Dunes Feb 10 '16 at 23:19
  • Seems to be an issue more to do with with ssh than python. Passing the `-f` option to ssh will achieve what you want. – Dunes Feb 10 '16 at 23:20
  • i have tried -f and it does not seem to work either. same result with or w/o -f . ret = subprocess.Popen(["ssh", "-f", "xxx@servername", "PATH/start"]) – hefeicoder Feb 11 '16 at 04:03

2 Answers2

1

After playing about a bit I found that nohup doesn't seem to be properly disconnecting the child process from the parent ssh session (as it should be). This means you have to manually close stdout or point it at a file, e.g.

Using bash:

ssh user@host "nohup PATH/XProgram >&- &"

Shell agnostic (as far as I know):

ssh user@host "nohup PATH/XProgram >/dev/null 2>&1 &"

In python:

from shlex import split
from subprocess import Popen

p = Popen(split('ssh user@host "nohup PATH/XProgram >&- &"'))
p.communicate() # returns (None, None)
fzbd
  • 477
  • 2
  • 8
Dunes
  • 37,291
  • 7
  • 81
  • 97
  • thanks, man. ">/dev/null 2>&1 &" works like a charm. But why redirection can causing nohup detach from SSH and let ssh exit normally ? – hefeicoder Feb 11 '16 at 03:55
0

Try

subprocess.Popen(["ssh", "xxx@servername", "nohup PATH/start & disown"])

For me,

subprocess.Popen(["ssh", "xxx@servername", "nohup sleep 1000 & disown"])

lets my script exit immediately while leaving sleep running on the server awhile.

When your script dies, an ssh process is left on your system, but killing it doesn't kill the remote process.

pjvandehaar
  • 1,070
  • 1
  • 10
  • 24