2

How can i run an external program, let's say "Firefox", from my python script and make sure that its process will remain alive after the termination of my python script? I want to make it crossplatform if it's doable.

specktator
  • 95
  • 1
  • 8
  • http://stackoverflow.com/questions/204017/how-do-i-execute-a-program-from-python-os-system-fails-due-to-spaces-in-path – jonjohnson Feb 16 '14 at 00:49
  • @jonjohnson: How does that answer this question, or even related to it? The question there is about a quoting problem with `os.system`, and the answer is to use `subprocess.call`, which will block until the child process finishes… – abarnert Feb 16 '14 at 00:54
  • related: [Popen waiting for child process even when the immediate child has terminated](http://stackoverflow.com/q/13243807/4279) – jfs Feb 18 '14 at 09:32

1 Answers1

1

There is no cross-platform way to do this with just the stdlib. However, if you write code for POSIX and for Windows, that's usually good enough, right?

On Windows, you want to pass a creationflags argument. Read the docs (both there and at MSDN) and decide whether you want a console-detached process, a new-console process, or a new-process-group process, then use the appropriate flag. You may also want to set some of the flags in startupinfo; again, MSDN will tell you what they mean.

On POSIX, if you just want the simplest behavior, and you're using 3.2+, you want to pass start_new_session=True. In earlier Python versions, or for other cases, you want to pass a preexec_fn that allows you to do whatever daemonization you want. That could be as little as os.setsid() (what start_new_session does), or a whole lot more. See PEP 3143 -- Standard daemon process library for a discussion of all of the different things you might want to do here.

So, the simplest version is:

def launch_in_background(args):
    try:
        subprocess.CREATE_NEW_PROCESS_GROUP
    except AttributeError:
        # not Windows, so assume POSIX; if not, we'll get a usable exception
        p = subprocess.Popen(args, start_new_session=True)
    else:
        # Windows
        p = subprocess.Popen(args, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)

If you're willing to go outside the stdlib, there are dozens of "shell-type functionality" libraries out there, many of which have some kind of "detach" functionality. Just search shell, cli, or subprocess at PyPI and find the one you like best.

abarnert
  • 354,177
  • 51
  • 601
  • 671