2017-07-20 3 views
0

Endlich habe ich es geschafft, den Prozess meines Skripts im Daemon zu konvertieren, und nach stundenlangem Testen stellte ich fest, dass das im Daemon konvertierte Skript keine Operationen wie ausführt :Mein Python-Skript als Daemon unterstützt das Öffnen und Schreiben von Outfiles nicht

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

Mein Skript funktioniert auf diese Weise:

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() 

gibt es eine Möglichkeit, meine Daemon Operationen zu ermöglichen, wie das Öffnen von Dateien und Schreiben von Dateien? Und aus Neugier, warum ein Daemon keine I/O-Operationen ausführen kann?

+0

Hat der Aufruf einen Fehler liefert zu schreiben? Wenn Sie es so aufrufen, wie Sie es im Beispiel angegeben haben, sollte es "PermissionError" auslösen, da Sie keine Rechte zum Schreiben in das '/' (weil es Ihr cwd ist) haben, es sei denn, Sie führen den Code als root aus. – Qeek

+0

Ja, du hast Recht. Also muss ich nur os.chdir ("/") mit dem Pfad meines Hauses ändern? – AllExJ

+0

Sie müssen nicht einmal 'os.chidr()' aufrufen, wenn Sie sicher sind, dass der cwd existiert, während Ihr Daemon läuft. Vorzugsweise sollten Sie absolute Pfade verwenden und Ordner wie '/ tmp /' verwenden. – Qeek

Antwort

0

Das os.chdir('/') Wechsel Arbeitsverzeichnis des Programms auf die /. Also ist jeder relative Pfad relativ zu /. Wenn Sie open("test.txt", "w") aufrufen, wie Sie im Beispiel angegeben haben, wird PermissionError ausgelöst, da Sie keine Rechte zum Schreiben in die Datei /test.txt haben, es sei denn, Sie führen das Programm als Root aus.

Sie haben diese Optionen:

  • immer absoluth Pfade verwenden
  • Set cwd zu Verzeichnis, in dem Sie die Erlaubnis
Verwandte Themen