Python process automatically restarting itself

Matimus mccredie at gmail.com
Thu Oct 11 13:55:25 EDT 2007


On Oct 11, 7:17 am, Adam Atlas <a... at atlas.st> wrote:
> 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




More information about the Python-list mailing list