I've tried running things like this:

subprocess.Popen(['nohup', 'my_command'],
                 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.


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)
        pid = os.fork() 
        if pid > 0:
            # parent process, return and keep running
    except OSError, e:


    # do second fork
        pid = os.fork() 
        if pid > 0:
            # exit from second parent
    except OSError, e: 

    # do stuff

    # all done
  • If I fork, and then I kill one half of the fork (rather than allowing it to exit), will that kill the new process? – James May 15 '11 at 22:59
  • 1
    Okay, after further reading: this requires forking twice to avoid receiving signals? I'd quite like the parent process to remain interactive --- its job is to monitor the processes that it spawns --- which isn't possible if it has to disown the shell. – James May 15 '11 at 23:02
  • Thanks! I've added my implementation to your answer. – James May 20 '11 at 14:10
  • This is great as it sets the daemon parent process ID to 1 so that it's completely disconnected from the parent. The subprocess command I ran from the other answer was killed by my Torque job scheduler, even when changing its process group because the parent process ID still matched the dying process. – storm_m2138 Feb 16 '17 at 19:45

The child process receives the same SIGINT as your parent process because it's in the same process group. You can put the child in its own process group by calling os.setpgrp() in the child process. Popen's preexec_fn argument is useful here:

subprocess.Popen(['nohup', 'my_command'],
                 stderr=open('logfile.log', 'a'),

(preexec_fn is for un*x-oids only. There appears to be a rough equivalent for Windows "creationflags=CREATE_NEW_PROCESS_GROUP", but I've never tried it.)

  • Thanks for your answer; it works for me! However, I am curious why my command stops (process dies) after some point, if I omit the stdout & stderr agruments. – danuker Dec 8 '17 at 13:09
  • 1
    maybe the stdout and stderr buffers fill up and the process becomes deadlocked? – Tom May 21 '18 at 0:01
  • If you are using shell=True then creationflags=subprocess.CREATE_NEW_CONSOLE is probably what you want – Pro Q Oct 13 '18 at 18:27

Your Answer

