Search code examples
pythonexecrestart

Python: Trying to restart script not working


Tried to restart my python script within itself. Python 2.7.11

#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import sys
os.execv(__file__, sys.argv)
sys.exit()

Result:

Traceback (most recent call last):
    File "...\foo.py", line 3, in <module>
        os.execv(__file__, sys.argv)
OSError: [Errno 8] Exec format error

Another code:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import sys
os.execv(sys.executable, [sys.executable] + sys.argv)
sys.exit()

Result:

C:\...\python.exe: can't open file 'C:\...\Math': [Errno 2] No such file or directory

The file's name is foo.py - it's in a folder name 'Math Project'

Codepage: 852, if necessary.


Solution

  • Your error message C:\...\python.exe suggests that you're running a Windows system.

    Your first script fails because under Windows, os.execv() doesn't know how to handle Python scripts because the first line (#!/usr/bin/python) is not evaluated nor does it point to a valid Python interpreter on most Windows systems. In effect, os.execv() tries to execute a plain text file which happens to contain Python code, but the system doesn't know that.

    Your second script fails to correctly retrieve the file name of your Python script foo.py. It's not clear to me why that happens, but the error message suggests that there might be a problem with the space in your directory name Math Project.

    As a possible workaround, try replacing the line

    os.execv(sys.executable, [sys.executable] + sys.argv)
    

    by the following:

    os.execv(sys.executable, 
             [sys.executable, os.path.join(sys.path[0], __file__)] + sys.argv[1:])
    

    This line attempts to reconstruct the correct path to your Python script, and pass it as an argument to the Python interpreter.

    As a side note: Keep in mind what your script is doing: it's unconditionally starting another instance of itself. This will result in an infinite loop, which will eventually bring down your system. Make sure that your real script contains an abort condition.

    EDIT:

    The problem lies, indeed, with the space in the path, and the workaround that I mentioned won't help. However, the subprocess module should take care of that. Use it like so:

    import os
    import sys
    import subprocess
    
    subprocess.call(["python", os.path.join(sys.path[0], __file__)] + sys.argv[1:])