python subprocess在后台运行远程进程并立即关闭连接

时间:2016-02-10 22:55:46

标签: python ssh subprocess

任务是使用python在后台运行远程进程并立即关闭ssh会话。

我在服务器下有一个远程脚本名称'start':PATH /,启动脚本什么也不做,只是午餐一个长期的后台程序。 'start'脚本有一行:

nohup PATH/Xprogram &

当我使用python子进程模块调用我的远程'start'脚本时,它确实启动了。但问题是:似乎SSH连接是持久的,这意味着我从远程Xprogram获得stdout(因为它是一个带有输出到stdout的长实时程序)。这是否仍然存在ssh连接?

我只需要在不阻塞的情况下调用启动脚本并忘记它(让长时间的程序保持运行,关闭ssh,释放资源)。

我的python函数调用如下所示:

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

如果我在命令之后使用ret.terminate(),那么它也会杀死长寿命程序。 我也试过了马刺模块。基本上是一回事。

=====更新====

@Dunes'的答案解决了这个问题。根据他的回答,我做了更多挖掘,发现this link非常有帮助。 我对此的理解是:基本上,如果你的进程仍然拥有任何文件描述符(例如我的XProgram持有的stdout),那么SSH会话将不会退出。但是,将stdout / stderr重定向到NULL会有效地关闭这些文件描述符,并使SSH会话正常退出。

解决方案

ret = subprocess.Popen(["ssh", "xxx@servername", "PATH/start >dev/null 2>&1"])

2 个答案:

答案 0 :(得分:0)

尝试

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

对我来说,

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

让我的脚本立即退出,同时让sleep在服务器上运行一段时间。

我认为只有&是必要的,但其他人也很有趣。

当您的脚本死亡时,系统会保留ssh进程,但kill它不会终止远程进程。

答案 1 :(得分:0)

在玩了一下之后,我发现nohup似乎没有正确地将子进程与父ssh会话断开连接(应该是这样)。这意味着您必须手动关闭stdout或将其指向文件。例如

使用bash:

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

Shell不可知(据我所知):

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

在python中:

from shlex import split
from subprocess import Popen

p = Popen(split('ssh user@host "hohup PATH/XProgram >&- &"'))
p.communicate() # returns (None, None)