Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to spawn a new independent process in Python

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.

like image 333
Marc Avatar asked Dec 17 '13 23:12

Marc


People also ask

Does subprocess create a new process?

Subprocess in Python is a module used to run new codes and applications by creating new processes. It lets you start new applications right from the Python program you are currently writing.

How do you spawn a process in Python?

The term "spawn" means the creation of a process by a parent process. The parent process can of course continue its execution asynchronously or wait until the child process ends its execution. The multiprocessing library of Python allows the spawning of a process through the following steps: Build the object process.

How to create and manage processes in Python?

Python provides the subprocess module in order to create and manage processes. The subprocess.popen () is one of the most useful methods which is used to create a process. This process can be used to run a command or execute binary. The process creation is also called as spawning a new process which is different from the current process.

How to start and join processes in Python?

I am Python') if __name__ == '__main__': p = Process(target=display) p.start() p.join() In this example, at first we import the Process class then initiate Process object with the display () function. Then process is started with start () method and then complete the process with the join () method.

Does Python-daemon create a completely independent process?

It does not create "a completely independent process" (that what python-daemon package does). Also, a child process won't get SIGPIPE in Python 2. Though in simple cases, your solution is enough (you should redirect to os.devnull child's stdin/stdout/stderr to avoid waiting for input and/or a spurious output to the terminal).


2 Answers

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) 
like image 110
Lasse Avatar answered Sep 28 '22 23:09

Lasse


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]) 
like image 32
Steve Barnes Avatar answered Sep 29 '22 01:09

Steve Barnes