远程启动后台Python程序

3 投票
2 回答
2357 浏览
提问于 2025-04-16 18:59

我需要用fabfile来远程启动一些程序,并获取结果。因为这些程序运行时间很长,我希望它们能在后台运行,这样我就不用一直等着了。于是我尝试使用os.fork()来实现这个功能。问题是,当我通过ssh连接到远程机器,并在那儿用os.fork()运行程序时,程序可以正常在后台运行。但是当我尝试用fabfile的run和sudo来远程启动程序时,os.fork()就不管用了,程序就悄无声息地死掉了。于是我转而使用Python-daemon来让程序在后台运行。起初,这个方法效果很好。但现在,当我开始让程序读取一些Python的shelve字典时,python-daemon就不再工作了。似乎如果使用python-daemon,shelve字典就无法正确加载,我也不知道为什么。有没有人能给我其他的建议,除了os.fork()和Python-daemon,我还可以尝试什么来解决我的问题?

2 个回答

2

对于将来看到这个帖子的人来说,Python-daemon 还是可以正常工作的。关键是要确保在同一个进程中加载 shelve 字典。之前,shelve 字典是在父进程中加载的,当 python-daemon 创建一个子进程时,字典的处理器没有正确传递。解决了这个问题后,一切又恢复正常了。

感谢在这个讨论中提出有价值建议的朋友们!

4

如果我理解你的问题没错,我觉得你把事情搞得太复杂了。os.fork() 是用来做多进程的,不是用来在后台运行程序的。

假设我们讨论一下,如果你想运行 program.sh 并收集它发送到标准输出的信息。要用 fabric 来做到这一点,你需要在本地创建一个文件:

fabfile.py:

from fabric.api import run
def runmyprogram():
    run('./program.sh > output 2> /dev/null < /dev/null &')

然后,在本地运行:

fab -H remotebox runmyprogram

这个程序会在远程执行,但 fabric 不会等它完成。你需要稍后去收集输出文件,可能要用 scp 命令。这里的 "&" 符号是让它在远程机器上后台运行,而输出重定向是必要的,目的是为了避免 fabric 会挂起

如果你不需要使用 fabric,还有更简单的方法来做到这一点。你可以单独使用 ssh 连接,然后运行:

nohup ./program.sh > output &

之后再回来查看输出。

如果这是你经常需要做的事情,这可能是更好的选择,因为你可以设置一个定时任务,让它定期运行,然后随时收集输出。

如果你不想稍后再去收集输出文件,你可以使用:

fabfile.py:

from fabric.api import run
def runmyprogram():
    run('./program.sh')

然后,在你的本地机器上:

fab -H remotebox runmyprogram > output &

这些任务会在远程运行,并把所有输出都放回到本地的输出文件里。这会在你的本地机器上后台运行,所以你可以做其他事情。不过,如果你和远程机器之间的连接可能会中断,最好还是使用第一种方法,这样输出总是安全地存储在远程机器上。

撰写回答