2017-08-29 46 views
0

好吧我正式运行每个样本后,我可以找到谷歌达到第19页的想法。我有一个“提供者”脚本。这个python脚本的目标是启动即使在这个“provider”停止运行之后无限期运行的其他服务。基本上,启动过程,然后忘了它,但继续脚本,而不是停止它...python-daemon启动一个独立的进程,但让主应用程序继续?

我的问题:python守护进程...我有行动(网络服务调用开始/停止/获取状态从开始服务)。我可以即时创建启动命令,并根据需要在配置文件上执行变量替换。

让我们从这一点开始:我有一个命令来运行(执行java进程的bash脚本 - 一段时间后会停止的长时间运行的服务)。

def start(command, working_directory): 
    pidfile = os.path.join(working_directory, 'application.pid') 
    # I expect the pid of the started application to be here. The file is not created. Nothing is there. 

    context = daemon.DaemonContext(working_directory=working_directory, 
            pidfile=daemon.pidfile.PIDLockFile(pidfile)) 
    with context: 
     psutil.Popen(command) 

    # This part never runs. Even if I put a simple print statement at this point, that never appears. Debugging in pycharms shows that my script returns with 0 on with context 
    with open(pidfile, 'r') as pf: 
     pid = pf.read() 

    return pid 

从我的来电显示这种方法我准备一个JSON对象返回基本上包含INSTANCE_ID(不介意吧)和PID客户端在这里(即会被用来阻止这种进程在另一个请求中

会发生什么?在上下文之后,我的应用程序以状态0退出,没有返回任何内容,没有创建json响应,没有创建pidfile只执行了psutil.Popen命令。我需要吗?我需要一个独立运行的进程,并且需要知道它的PID以便稍后停止它。即使当前python脚本由于某种原因而停止,执行的进程也必须运行。我无法绕过shell脚本美联社折磨不是我的,我必须使用我的东西。

感谢您的任何提示!

@编辑: 我试着用psutil/subprocess简单地使用Popen,结果稍好些。

def start(self, command): 
    import psutil/subprocess 

    proc = psutil.Popen(command) 

    return str(proc.pid) 

现在如果我调试应用程序,并等待一些不确定的时间对return语句的一切是伟大的工作!该服务正在运行pid,稍后停止。然后,我只需运行提供程序而不用调试。它返回pid,但进程没有运行。似乎像Popen没有时间开始这项服务,因为整个供应商停止更快。

@Update: 使用os.fork:

@staticmethod 
def __start_process(command, working_directory): 
    pid = os.fork() 
    if pid == 0: 
     os.chdir(working_directory) 
     proc = psutil.Popen(command) 
     with open('application.pid', 'w') as pf: 
      pf.write(proc.pid) 

def start(self): 
    ... 
    __start_process(command, working_directory) 
    with open(os.path.join(working_directory, 'application.pid'), 'r') as pf: 
     pid = int(pf.read()) 

    proc = psutil.Process(pid) 
    print("RUNNING" if proc.status() == psutil.STATUS_RUNNING else "...") 

运行上述样品后,RUNNING是写在控制台。主脚本退出后因为速度不够快:

ps auxf | grep 没有实例正在运行...

检查pidfile;确保它有它的创建

猫/application.pid EMPTY 0bytes

回答

0

从多个局部提示我有,终于设法得到它的工作...

def start(command, working_directory): 
    pid = os.fork() 
    if pid == 0: 
     os.setsid() 
     os.umask(0) # I'm not sure about this, not on my notebook at the moment 
     os.execv(command[0], command) # This was strange as i needed to use the name of the shell script twice: command argv[0] [args]. Upon using ksh as command i got a nice error... 
    else: 
     with open(os.path.join(working_directory, 'application.pid'), 'w') as pf: 
      pf.write(str(pid)) 

     return pid 

一起解决这个问题。启动的进程不是运行python脚本的子进程,并且在脚本终止时不会停止。

1

您是否尝试过与os.fork()

简而言之,os.fork()衍生出一个新进程并返回该新进程的PID。

你可以做这样的事情:

#!/usr/bin/env python 

import os 
import subprocess 
import sys 
import time 

command = 'ls' # YOUR COMMAND 
working_directory = '/etc' # YOUR WORKING DIRECTORY 

def child(command, directory): 
    print "I'm the child process, will execute '%s' in '%s'" % (command, directory) 
    # Change working directory 
    os.chdir(directory) 
    # Execute command 
    cmd = subprocess.Popen(command 
     , shell=True 
     , stdout=subprocess.PIPE 
     , stderr=subprocess.PIPE 
     , stdin=subprocess.PIPE 
    ) 
    # Retrieve output and error(s), if any 
    output = cmd.stdout.read() + cmd.stderr.read() 
    print output 
    # Exiting 
    print 'Child process ending now' 
    sys.exit(0) 

def main(): 
    print "I'm the main process" 
    pid = os.fork() 
    if pid == 0: 
     child(command, working_directory) 
    else: 
     print 'A subprocess was created with PID: %s' % pid 
     # Do stuff here ... 
     time.sleep(5) 
     print 'Main process ending now.' 
     sys.exit(0) 

if __name__ == '__main__': 
    main() 

进一步信息:

+0

在原文中查看我的更新。好的提示,我已经尝试过,没有任何成功。 –