I have a python-based GTK application that loads several modules. It is run from the (linux) terminal like so:
./myscript.py --some-flag setting
I know this solution isn't technically what you are asking for but if you want to be 100% sure you freed everything or don't want to rely on dependencies you could just run the script in from a loop in another:
import os, time
while 1:
os.system("python main.py")
print "Restarting..."
time.sleep(0.2) # 200ms to CTR+C twice
Then you can restart main.py as simply as:
quit()
Works at Windows (Without args)
os.startfile(__file__)
sys.exit()
OR
os.startfile(sys.argv[0])
sys.exit()
I have just a little amelioration on the code of #s3niOr.
In my case there are spaces in the path of the python file. So by adding a proper formatting, the problem can be solved.
Notice that in my case my python file has no other arguments. So if you do have other arguments, you have to deal with them.
This solves the problem of restarting a python script that has spaces in its path :
import os
import sys
import psutil
import logging
def restart_program():
"""Restarts the current program, with file objects and descriptors
cleanup
"""
try:
p = psutil.Process(os.getpid())
for handler in p.get_open_files() + p.connections():
os.close(handler.fd)
except Exception, e:
logging.error(e)
python = sys.executable
os.execl(python, python, "\"{}\"".format(sys.argv[0]))
UPDATE - of the above answer with some example for future reference
I have runme.sh
#!/bin/bash
kill -9 server.py
python /home/sun/workspace/c/src/server.py &
And i have server.py
where i need to restart the application itself, so i had:
os.system('runme.sh')
but that did not restart the application itself by following runme.sh, so when i used this way:
os.execl('runme.sh', '')
Then i was able to restart itself
I was looking for a solution to this and found nothing that works on any of the stack overflow posts. Maybe some of the answers are too out of date, e.g. os.system has been replaced by subprocess. I am on linux lubuntu 17.10, using python 3.
Two methods worked for me. Both open a new shell window and run the main.py script in it and then close the old one.
1. Using main.py with an .sh script.
Adapted from @YumYumYum method. I did not need the kill option, (though it did not kill my python process by name anyway and I had to use killall python3
to achieve it when testing).
I use lxterminal but you could probably use any.
In the file called restart.sh (chmod +x to make it executable)
#!/bin/bash
lxterminal -e python3 /home/my/folder/main.py &
Then in the main.py use this when you need to call it
import subprocess
subprocess.run('/home/my/folder/restart.sh', shell=True)
quit()
2. From within main.py
Adapted from @Stuffe method. This one is internal to the main.py script and opens a new shell window then runs the new script, then quits out of the old script. I am not sure it needs the time.sleep delay but I used it anyway.
import subprocess, time
cmd = 'python3 /home/my/folder/main.py'
subprocess.run('lxterminal -e ' + cmd, shell=True)
time.sleep(0.2)
quit()
I'm using this to give an option for the users to restart the script within the console. Hope it could be a help.
def close_restart(self,csvfile):
choice = input('Do you want to restart the program? Please select \'Y\' if you would like to restart.')
if choice == 'Y' or choice == 'y':
print('Restarting now...')
os.execl(sys.executable, sys.executable, *sys.argv)
else:
print('Thank you for using the tool!')
print('The program will close in 10s...')
time.sleep(10)
So the user can input an option 'Y/N' to restart the program or not.