How to spawn a new independent process in Python

Each Answer to this Q is separated by one/two green lines.

I have a some Python code that occasionally needs to span a new process to run a shell script in a “fire and forget” manner, i.e. without blocking. The shell script will not communicate with the original Python code and will in fact probably terminate the calling Python process, so the launched shell script cannot be a child process of the calling Python process. I need it to be launched as an independent process.

In other words, let’s say I have mycode.py and that launches script.sh. Then mycode.py will continue processing without blocking. The script script.sh will do some things independently and will then actually stop and restart mycode.py. So the process that runs script.py must be completely independent of mycode.py. How exactly can I do this? I think subprocess.Popen will not block, but will still create a child process that terminates as soon as mycode.py stops, which is not what I want.

Try prepending “nohup” to script.sh. You’ll probably need to decide what to do with stdout and stderr; I just drop it in the example.

import os
from subprocess import Popen

devnull = open(os.devnull, 'wb') # Use this in Python < 3.3
# Python >= 3.3 has subprocess.DEVNULL
Popen(['nohup', 'script.sh'], stdout=devnull, stderr=devnull)

Just use subprocess.Popen. The following works OK for me on Windows XP / Windows 7 and Python 2.5.4, 2.6.6, and 2.7.4. And after being converted with py2exe – not tried 3.3 – it comes from the need to delete expired test software on the clients machine.

import os
import subprocess
import sys
from tempfile import gettempdir

def ExitAndDestroy(ProgPath):
    """ Exit and destroy """
    absp = os.path.abspath(ProgPath)
    fn = os.path.join(gettempdir(), 'SelfDestruct.bat')
    script_lines = [
        '@rem Self Destruct Script',
        '@echo ERROR - Attempting to run expired test only software',
        '@pause',
        '@del /F /Q %s' % (absp),
        '@echo Deleted Offending File!',
        '@del /F /Q %s\n' % (fn),
        #'@exit\n',
        ]
    bf = open(fn, 'wt')
    bf.write('\n'.join(script_lines))
    bf.flush()
    bf.close()
    p = subprocess.Popen([fn], shell=False)
    sys.exit(-1)

if __name__ == "__main__":
   ExitAndDestroy(sys.argv[0])


The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .