I've tried running things like this:
subprocess.Popen(['nohup', 'my_command'], stdout=open('/dev/null', 'w'), 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.
sleep() Function To Run Script repeatedly. So, if you do not want to use the above code and just want to run your script repeatedly then you can use the time. sleep() function. This function allows your script to keep running after sleeping for a certain amount of time.
kill() method in Python is used to send specified signal to the process with specified process id. Constants for the specific signals available on the host platform are defined in the signal module. Parameters: pid: An integer value representing process id to which signal is to be sent.
You can kill a process via its process identifier, pid, via the os. kill() function.
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'], stdout=open('/dev/null', 'w'), stderr=open('logfile.log', 'a'), preexec_fn=os.setpgrp )
(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.)
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) try: pid = os.fork() if pid > 0: # parent process, return and keep running return except OSError, e: print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror) sys.exit(1) os.setsid() # do second fork try: pid = os.fork() if pid > 0: # exit from second parent sys.exit(0) except OSError, e: print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror) sys.exit(1) # do stuff func() # all done os._exit(os.EX_OK)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With