我正在尝试使用以下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))
答案 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)
正如我的实验,解决方案是两个因素的组合:
所以,你的函数应该是这样的:
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
对我不起作用,并且我没有在要使用它的所有盒子上安装tmux
或dtach
,所以我最终使用了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 -m
和pty=False
/ sleep 1
都没有为我正常工作.YMMV,尤其是因为我不知道为什么这有效...)