简体   繁体   中英

python subprocess run a remote process in background and immediately close the connection

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 (eg 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"])

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, eg

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)

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 kill ing it doesn't kill the remote process.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM