2017-08-29 45 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

在原文中查看我的更新。好的提示,我已經嘗試過,沒有任何成功。 –