2017-07-20 12 views
0

私は最終的に私のスクリプトのプロセスをデーモンで変換することができました。テストの時間を経て、デーモンで変換されたスクリプトは、 :ファイルを開くと、ファイルを書き込むように私のデーモンの操作を許可する方法はデーモンとしての私のPythonスクリプトは、オープンファイルとアウトファイルの書き出しをサポートしていません

class daemon: # taken here https://web.archive.org/web/20160305151936/http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/ 
    """A generic daemon class. 

    Usage: subclass the daemon class and override the run() method.""" 

    def __init__(self, pidfile): 
     self.pidfile = pidfile 
     self.main = main 

    def daemonize(self): 
     """Deamonize class. UNIX double fork mechanism.""" 

     try: 
      pid = os.fork() 
      if pid > 0: 
       # exit first parent 
       sys.exit(0) 
     except OSError as err: 
      sys.stderr.write('fork #1 failed: {0}\n'.format(err)) 
      sys.exit(1) 

     # decouple from parent environment 
     os.chdir('/') 
     os.setsid() 
     os.umask(0) 

     # do second fork 
     try: 
      pid = os.fork() 
      if pid > 0: 

       # exit from second parent 
       sys.exit(0) 
     except OSError as err: 
      sys.stderr.write('fork #2 failed: {0}\n'.format(err)) 
      sys.exit(1) 

     # redirect standard file descriptors 
     sys.stdout.flush() 
     sys.stderr.flush() 
     si = open(os.devnull, 'r') 
     so = open(os.devnull, 'a+') 
     se = open(os.devnull, 'a+') 

     os.dup2(si.fileno(), sys.stdin.fileno()) 
     os.dup2(so.fileno(), sys.stdout.fileno()) 
     os.dup2(se.fileno(), sys.stderr.fileno()) 

     # write pidfile 
     atexit.register(self.delpid) 

     pid = str(os.getpid()) 
     with open(self.pidfile,'w+') as f: 
      f.write(pid + '\n') 

    def delpid(self): 
     os.remove(self.pidfile) 

    def start(self): 
     """Start the daemon.""" 

     # Check for a pidfile to see if the daemon already runs 
     try: 
      with open(self.pidfile,'r') as pf: 

       pid = int(pf.read().strip()) 
     except IOError: 
      pid = None 

     if pid: 
      self.restart() 

     # Start the daemon 
     self.daemonize() 
     self.run() 

    def stop(self): 
     """Stop the daemon.""" 

     # Get the pid from the pidfile 
     try: 
      with open(self.pidfile,'r') as pf: 
       pid = int(pf.read().strip()) 
     except IOError: 
      pid = None 

     if not pid: 
      message = "pidfile {0} does not exist. " + \ 
        "Daemon not running?\n" 
      sys.stderr.write(message.format(self.pidfile)) 
      return # not an error in a restart 

     # Try killing the daemon process  
     try: 
      while 1: 
       os.kill(pid, signal.SIGTERM) 
       time.sleep(0.1) 
     except OSError as err: 
      e = str(err.args) 
      if e.find("No such process") > 0: 
       if os.path.exists(self.pidfile): 
        os.remove(self.pidfile) 
      else: 
       print (str(err.args)) 
       sys.exit(1) 

    def restart(self): 
     """Restart the daemon.""" 
     self.stop() 
     self.start() 

    def run(self): 
     """You should override this method when you subclass Daemon. 

     It will be called after the process has been daemonized by 
     start() or restart().""" 
     while True: 
      self.main() 

def main(): 
    # several and various operations 

if __name__ == "__main__": 
    d = daemon('/tmp/daemon-example.pid') 
    d.start() 

あります:

out_file = open("test.txt","w") 
out_file.write("") 
out_file.close() 

私のスクリプトは、このように動作しますか?また、好奇心のために、デーモンがI/O操作を行うことができないのはなぜですか?

+0

呼び出しがエラーを提供していますが書き込み権限を持っているディレクトリにabsoluthパス

  • セットCWDを使うのか?この例で指定したように呼び出すと、ルートとしてコードを実行している場合を除き、 '/'で書くことができる権限がないため、 'PermissionError'が発生します。 – Qeek

  • +0

    ええ、あなたは正しいです。ですから、私の家の経路でos.chdir( "/")を変更するだけです。 – AllExJ

    +0

    デーモンの実行中にcwdが存在することが確かな場合は、 'os.chidr()'を呼び出す必要はありません。絶対パスを使用し、 '/ tmp /'のようなフォルダを使うのが望ましいでしょう。 – Qeek

    答えて

    0

    os.chdir('/')プログラムの作業ディレクトリを/に変更してください。したがって、すべての相対パスは/に相対的です。この例のようにopen("test.txt", "w")を呼び出すと、プログラムをルートとして実行していない限り、/test.txtに書き込む権限がないため、PermissionErrorが発生します。

    あなたはそれらのオプションを持っている:

    • は常にあなたが
    関連する問題