使用fabric开始使用nohup的后台进程

时间:2012-01-08 05:26:02

标签: python fabric

我正在尝试使用以下nohup命令使用fabric启动celerycam进程。不幸的是,没有任何事情发生,手动使用相同的命令我可以启动过程但不通过结构。关于我如何解决这个问题的任何建议?

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 个答案:

答案 0 :(得分:30)

我正在使用Erich Heine的建议来使用'dtach'并且它对我来说非常好用:

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

找到here

答案 1 :(得分:17)

正如我的实验,解决方案是两个因素的组合:

  • 将流程作为守护程序运行:nohup ./command&> / dev / null&
  • 使用 pty = False 进行结构运行

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

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

您可以使用以下命令启动它:

execute(background_run, your_command)

答案 2 :(得分:8)

这是this issue的一个实例。命令结束时将终止后台进程。不幸的是,CentOS 6不支持pty-less sudo命令。

问题的最后一个条目是使用sudo('set -m; service servicename start')提及的。这将打开作业控制,因此后台进程将放入其自己的进程组中。因此,当命令结束时,它们不会被终止。

有关更多信息,请参阅this链接。

答案 3 :(得分:5)

你只需要运行

run("(nohup yourcommand >& /dev/null < /dev/null &) && sleep 1")

答案 4 :(得分:3)

DTACH是要走的路。这是一个软件,你需要安装像精简版的屏幕。 这是上面找到的“dtach”方法的更好版本,如果需要,它将安装dtach。可以找到here,您还可以在其中学习如何获取在后台运行的进程的输出:

from fabric.api import run
from fabric.api import sudo
from fabric.contrib.files import exists


def run_bg(cmd, before=None, sockname="dtach", use_sudo=False):
    """Run a command in the background using dtach

    :param cmd: The command to run
    :param output_file: The file to send all of the output to.
    :param before: The command to run before the dtach. E.g. exporting
                   environment variable
    :param sockname: The socket name to use for the temp file
    :param use_sudo: Whether or not to use sudo
    """
    if not exists("/usr/bin/dtach"):
        sudo("apt-get install dtach")
    if before:
        cmd = "{}; dtach -n `mktemp -u /tmp/{}.XXXX` {}".format(
            before, sockname, cmd)
    else:
        cmd = "dtach -n `mktemp -u /tmp/{}.XXXX` {}".format(sockname, cmd)
    if use_sudo:
        return sudo(cmd)
    else:
        return run(cmd)

这可以帮助你,就像它帮助我在远程rasberry pi上通过面料运行omxplayer一样!

答案 5 :(得分:1)

您可能会遇到this issue

尝试将'pty = False'添加到sudo命令(我假设virtualenv正在调用sudo或在某处运行?)

答案 6 :(得分:1)

这对我有用:

sudo('python %s/manage.py celerycam --detach --pidfile=celerycam.pid' % siteDir)

编辑:我必须确保首先删除了pid文件,因此这是完整的代码:

# Create new celerycam
sudo('rm celerycam.pid', warn_only=True)
sudo('python %s/manage.py celerycam --detach --pidfile=celerycam.pid' % siteDir)

答案 7 :(得分:1)

您可以使用:

run('nohup /home/ubuntu/spider/bin/python3 /home/ubuntu/spider/Desktop/baidu_index/baidu_index.py > /home/ubuntu/spider/Desktop/baidu_index/baidu_index.py.log 2>&1 &', pty=False)

答案 8 :(得分:1)

nohup对我不起作用,并且我没有在要使用它的所有盒子上安装tmuxdtach,所以我最终使用了screen像这样:

run("screen -d -m bash -c '{}'".format(command), pty=False)

这告诉屏幕在运行命令的独立终端中启动bash shell

答案 9 :(得分:0)

我能够通过在单独的本地shell脚本中运行nohup ... &而非ssh来解决此问题。在fabfile.py

@task
def startup():
    local('./do-stuff-in-background.sh {0}'.format(env.host))

do-stuff-in-background.sh

#!/bin/sh

set -e
set -o nounset

HOST=$1

ssh $HOST -T << HERE
   nohup df -h 1>>~/df.log 2>>~/df.err &
HERE

当然,您也可以将命令和标准输出/错误日志文件作为参数传递,以使此脚本更有用。

(在我的情况下,我没有安装dtach的管理员权限,screen -d -mpty=False / sleep 1都没有为我正常工作.YMMV,尤其是因为我不知道为什么这有效...)