16

I have a python script and I want to launch an independent daemon process. I want to call ym python script, launch this system tray dameon, do some python magic on a database file and quit, leaving the system tray daemon running.

I have tried os.system, subprocess.call, subprocess.Popen, os.execl, but it always keeps my script alive until I close the system tray daemon.

This sounds like it should be a simple solution, but I can't get anything to work.

vvvvv
  • 25,404
  • 19
  • 49
  • 81
Jtgrenz
  • 591
  • 1
  • 6
  • 21
  • 1
    A search would have found the answer. http://stackoverflow.com/questions/1196074/starting-a-background-process-in-python – sean Jul 20 '12 at 18:45
  • 2
    Yeah, I found that but it doesn't work. The script just hangs for a few seconds, doesn't launch the second process and doesn't execute the rest of the script. then it dies. I don't post question without searching and trying to figure it out on my own first. – Jtgrenz Jul 20 '12 at 18:50
  • Ah, ok sorry for the harshness then. Hmm, odd I'll check something and then get back if I figure it out. – sean Jul 20 '12 at 18:52
  • I did forget to include `os.spawn*` in the original post however. It was one of the first ones I tried before giving up for a few hours to clear my head and get lunch. – Jtgrenz Jul 20 '12 at 18:55

3 Answers3

10

You can use a couple nifty Popen parameters to accomplish a truly detached process on Windows (thanks to greenhat for his answer here):

import subprocess

DETACHED_PROCESS = 0x00000008
results = subprocess.Popen(['notepad.exe'],
                           close_fds=True, creationflags=DETACHED_PROCESS)
print(results.pid)

See also this answer for a nifty cross-platform version (make sure to add close_fds though as it is critical for Windows).

Community
  • 1
  • 1
jtpereyda
  • 6,987
  • 10
  • 51
  • 80
  • This works for me, and should be the accepted answer IMO. It still allows passing args, which the accepted answer does not. – Matt Huggins Oct 24 '19 at 20:22
8

Solution for Windows: os.startfile()

Works as if you double clicked an executable and causes it to launch independently. A very handy one liner.

http://docs.python.org/library/os.html?highlight=startfile#os.startfile

Jtgrenz
  • 591
  • 1
  • 6
  • 21
2

I would recommend using the double-fork method.

Example:

import os
import sys
import time

def main():
    fh = open('log', 'a')
    while True:
        fh.write('Still alive!')
        fh.flush()
        time.sleep(1)

def _fork():
    try: 
        pid = os.fork() 
        if pid > 0:
            sys.exit(0) 
    except OSError, e: 
        print >>sys.stderr, 'Unable to fork: %d (%s)' % (e.errno, e.strerror) 
        sys.exit(1)


def fork():
    _fork()

    # remove references from the main process
    os.chdir('/')
    os.setsid()
    os.umask(0)

    _fork()

if __name__ == '__main__':
    fork()
    main()
Wolph
  • 78,177
  • 11
  • 137
  • 148