Search code examples
pythonsubprocessnohup

Run a program from python, and have it continue to run after the script is killed


I've tried running things like this:

subprocess.Popen(['nohup', 'my_command'],
                 stdout=open('/dev/null', 'w'),
                 stderr=open('logfile.log', 'a'))

This works if the parent script exits gracefully, but if I kill the script (Ctrl-C), all my child processes are killed too. Is there a way to avoid this?

The platforms I care about are OS X and Linux, using Python 2.6 and Python 2.7.


Solution

  • The usual way to do this on Unix systems is to fork and exit if you're the parent. Have a look at os.fork() .

    Here's a function that does the job:

    def spawnDaemon(func):
        # do the UNIX double-fork magic, see Stevens' "Advanced 
        # Programming in the UNIX Environment" for details (ISBN 0201563177)
        try: 
            pid = os.fork() 
            if pid > 0:
                # parent process, return and keep running
                return
        except OSError, e:
            print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror) 
            sys.exit(1)
    
        os.setsid()
    
        # do second fork
        try: 
            pid = os.fork() 
            if pid > 0:
                # exit from second parent
                sys.exit(0) 
        except OSError, e: 
            print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror) 
            sys.exit(1)
    
        # do stuff
        func()
    
        # all done
        os._exit(os.EX_OK)