如何使用Fabric通过nohup启动后台进程?

29 投票
10 回答
18091 浏览
提问于 2025-04-17 09:46

我正在通过Fabric来启动一个celerycam进程,使用下面的nohup命令。但是很不幸,什么都没有发生。手动使用相同的命令时,我可以成功启动这个进程,但通过Fabric却不行。有没有什么建议可以帮我解决这个问题?

def start_celerycam():
    '''Start celerycam daemon'''
    with cd(env.project_dir):
        virtualenv('nohup bash -c "python manage.py celerycam --logfile=%scelerycam.log --pidfile=%scelerycam.pid &> %scelerycam.nohup &> %scelerycam.err" &' % (env.celery_log_dir,env.celery_log_dir,env.celery_log_dir,env.celery_log_dir))

        

10 个回答

8

这是一个关于这个问题的例子。当命令结束时,后台进程会被杀掉。不幸的是,在CentOS 6上不支持没有伪终端的sudo命令。

在这个问题的最后一条提到可以使用sudo('set -m; service servicename start')。这个命令开启了作业控制,因此后台进程会被放在自己的进程组里。这样一来,当命令结束时,它们就不会被终止了。

想了解更多信息,可以查看这个链接。

21

根据我的实验,解决方案是由两个因素组合而成的:

  • 将进程作为一个守护进程运行:使用命令 nohup ./command &> /dev/null &
  • 在 fabric 运行时使用pty=False

所以,你的函数应该像这样:

def background_run(command):
    command = 'nohup %s &> /dev/null &' % command
    run(command, pty=False)

你可以用以下方式启动它:

execute(background_run, your_command)
32

我正在使用Erich Heine的建议,使用'dtach',效果还不错:

def runbg(cmd, sockname="dtach"):
    return run('dtach -n `mktemp -u /tmp/%s.XXXX` %s' % (sockname, cmd))

这个信息可以在这里找到。

撰写回答