代码之家  ›  专栏  ›  技术社区  ›  Allexj

我的Python脚本作为守护进程不支持打开和写入外部文件

  •  0
  • Allexj  · 技术社区  · 7 年前

    我最终设法在daemon中转换了脚本的进程,经过数小时的测试,我发现在daemon中转换的脚本不会执行以下操作:

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

    我的脚本是这样工作的:

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

    1 回复  |  直到 7 年前
        1
  •  0
  •   Qeek    7 年前

    这个 os.chdir('/') 将程序的工作目录更改为 / 所以每个相对路径都是相对于 / open("test.txt", "w") 正如您在示例中所提供的,它会引发PermissionError,因为您没有在 /test.txt 除非您以根用户身份运行程序。

    您可以选择:

    • 将cwd设置为您有写权限的目录