Python process automatically restarting itself

A

Adam Atlas

What is the best way for a Python process (presumed to be a script run
by the interpreter binary, not embedded in some other program) to
restart itself? This is what I've been trying:

import __main__

for path in sys.path:
path += '/' + __main__.__file__
if os.access(path, os.F_OK): break
else:
raise Exception('WTF?')

#Then, something like...
os.execl(sys.executable, sys.executable, path, *sys.argv[1:])

BUT! This is a multi-threaded program, and at least on OS X, trying to
exec*() in a threaded process raises OSError [Errno 45] Operation not
supported. So I tried having it fork, and having the child process
wait for the parent process to die (in various ways) and then exec*().
That seemed to work, sort of, but the child would not be attached to
the original terminal, which is a must.

Any ideas?
 
M

Matimus

What is the best way for a Python process (presumed to be a script run
by the interpreter binary, not embedded in some other program) to
restart itself? This is what I've been trying:

import __main__

for path in sys.path:
path += '/' + __main__.__file__
if os.access(path, os.F_OK): break
else:
raise Exception('WTF?')

#Then, something like...
os.execl(sys.executable, sys.executable, path, *sys.argv[1:])

BUT! This is a multi-threaded program, and at least on OS X, trying to
exec*() in a threaded process raises OSError [Errno 45] Operation not
supported. So I tried having it fork, and having the child process
wait for the parent process to die (in various ways) and then exec*().
That seemed to work, sort of, but the child would not be attached to
the original terminal, which is a must.

Any ideas?

sys.path is the search path that Python uses for finding modules, and
probably isn't what you wanted. Also, it is bad practice to hard code
the file separator. In general you will want to do this:

import os.path
path = os.path.join(path, filename)

which will automatically insert the correct separator for the os you
are using.

That is moot though, since I think this is a better solution:

import os.path, __main__
path = os.path.abspath(__main__.__file__)

That isn't really necessary though. In fact, I think restarting the
process using exec* is the wrong way to go. I would simply encapsulate
my program inside of a function, set a restart flag, return from said
function and restart if the flag was set.

Something like this:

restart = False
def main():
# do my stuff

if need_to_restart:
global restart
restart = True

#do clean-up (shut down threads, etc.)
return retval

if __name__ == "__main__":
retval = main()
while restart:
restart = False
retval = main()
sys.exit(retval)

I suppose there are reasons that you might want to restart the
process. Most of the time you are going to want to do something like
what I suggested though. And even in those other cases, you probably
want to use the subprocess module instead of an exec* function.

Matt
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,021
Latest member
AkilahJaim

Latest Threads

Top