PYTHON RESTART SCRIPT ON ERROR

AMQPBashsibbap.orgbook reviewbugC++careerCeleryclusteringformal languagesGitHTTPjournalsLaTeXLinuxmanagementmockprogrammingprojectPythonRabbitMQresearchRustsocketsssdeepterminaltestingTmuxVimwebsiteWeeChat

Sometimes, you may wish to examine within a script as soon as a configuration file or the script itself alters, and if so, then instantly restart the manuscript. In this short article, you will view a means of doing this in Python.Consider the following scenario. You have actually a Python script that runs as a daemon and also frequently performs the prescribed tasks. Instances might be a internet server, a logging organization, and also a device monitor. When the manuscript starts, it reads its configuration from a paper, and then enters an infinite loop. In this loop, it waits for inputs from the environment and acts upon them. For instance, a internet server may react to a repursuit for a page, which results right into sending an answer to the user.

You watching: Python restart script on error

From time to time, it may be vital to rebegin the manuscript. For instance, if you deal with a bug in it or change its configuration. One way of doing so is to kill the manuscript and also run it aget. However, this needs hands-on intervention, which you might forobtain to carry out. When you fix a vulnercapacity in the script, you want to be sure that you perform not forobtain to rebegin the manuscript. Otherwise, someone might manipulate the vulnerability if you did not restart the manuscript. It would be nice if tbelow existed a means of refounding the manuscript within itself after it detected that its sources or a configuration file changed. In the rest of this post, we will certainly show such a means.

For the purpose of the existing post, let us assume that the script has actually the complying with structure:

# Parse the arguments and also configuration documents.while True: # Wait for inputs and act on them. # ...That is, it procedures the arguments and loads the configuration from the configuration files. After that, the script waits for inputs and also processes them in an infinite loop.

Next off, we describe how to watch papers for changes. After that, we present how to restart the script.

Checking Watched Files For Changes

First, we specify the routes to the records whose change we desire to watch:

WATCHED_FILES = We watch the global configuration file, the local configuration file, and also the manuscript itself, whose course have the right to be acquired from the unique worldwide variable __file__. When the manuscript starts, we acquire and also save the moment of the last modification of these documents by making use of os.path.getmtime():

from os.route import getmtimeWATCHED_FILES_MTIMES = <(f, getmtime(f)) for f in WATCHED_FILES>Then, we include a inspect if any kind of of these records have actually adjusted into the major loop:

while True: for f, mtime in WATCHED_FILES_MTIMES: if getmtime(f) != mtime: # Restart the script. # Wait for inputs and also act on them. # ...If either of the papers that we watch has actually adjusted, we rebegin the manuscript. The rebeginning is explained following.

Restarting the Script

We rebegin the script by utilizing one of the exec*() features from the os module. The exact version and arguments depfinish on just how you run the script. For example, on Linux or Mac OS, you deserve to make the file executable by placing the complying with line to the height of the file

#!/usr/bin/env pythonand executing

$ chmod a+x daemon.pyThen, you deserve to run the manuscript via

$ ./daemon.pyIn such a situation, to restart the manuscript, usage the following code:

os.execv(__file__, sys.argv)Otherwise, once you run the script via

$ python daemon.pyuse this code:

os.execv(sys.executable, <"python"> + sys.argv)Either way, perform not forget to import the sys module:

import sysTo describe, the debates of os.execv() are the regime to replace the present process via and also disagreements to this regime. The __file__ variable holds a route to the manuscript, sys.argv are debates that were passed to the manuscript, and sys.executable is a route to the Python executable that was used to run the manuscript.

The os.execv() function does not return. Instead, it starts executing the current script from its beginning, which is what we want.

See more: Book Review Tuesdays With Morrie ? Tuesdays With Morrie

Concluding Remarks

If you use the solution above, please bear in mind that the exec*() attributes cause the present process to be reput instantly, without flushing opened file objects. Therefore, if you have any kind of opened documents at the moment of rebeginning the script, you must flush them making use of f.flush() or os.fsync(fd) before calling an exec*() feature.

Of course, the presented solution is just among the feasible means of refounding a Python script. Depfinishing on the actual case, other ideologies, favor killing the script externally and starting it after that, might be even more suitable for you. Furthermore, there exist various other methods of checking whether a watched file has adjusted and acting upon such a readjust. If you recognize of an additional means of rebeginning a Python regimen within itself, please share it by posting a comment.

Complete Source Code

The complete resource code for this short article is easily accessible on GitHub.


*
Justin

Petr,

This looks to be specifically what I am in search of.I am extremely new to Python though so I am struggling figuring out just how specifically to implement this.I have actually a cron task that runs (allows speak to it routine A) eextremely night at midnight and goes to a webservice and checks to see if i have actually updated my code to my routine (lets call it regime B). If I have actually, it downlots the code and overwrites my routine B code. Until understand I couldn’t acquire regime A to restart regimen B. So I set up a cron job that just reboots the PI eincredibly night. I don’t choose this and would really favor Program B to pick up the readjust and also restart itself only if tright here has actually been a change. I am struggling on wright here to put this while loop in my code.

allows say i have actually a sheight watch routine that fundamentally mirrors a clock and a stop watch at the same time. Its constantly waiting on outside inputs from GPIO to start and stop the stop watch and also document their times. I tried placing your loop at the peak and the bottom but my code either goes right into an infinite loop or doesn’t screen the major regime. Any advice you might give would certainly be appreciated.

def main(): root = Tk() FS = FullScreenApp(root) cf = ConfigFile(root) framework = Frame(root) application = App(root) sw = StopWatch(root) root.mainloop()

*
Petr Zemek
Hi Justin!

You need to put the checking and restarting into a area that is periodically executed. For example, in a Tk application, this deserve to be done by making use of root.after() as follows:

#!/usr/bin/env pythonimport osimport sys# If you use Python 2, replace tkinter with Tkinter.from tkinter import Tk# Number of milliseconds after which a examine whether# the file has readjusted is performed.CHECK_INTERVAL = 2000# Last time the file was modified.last_mtime = os.route.getmtime(__file__)# The major window.root = Tk()def restart_if_changed(): # Check if the file has actually readjusted. # If so, restart the application. if os.route.getmtime(__file__) > last_mtime: print("file has actually readjusted => restarting") # Restart the application (os.execv() does not return). os.execv(__file__, sys.argv) # Reschedule the checking. root.after(CHECK_INTERVAL, restart_if_changed)# Schedule the checking.root.after(CHECK_INTERVAL, restart_if_changed)# Go into the main processing loop.root.mainloop()Just conserve the code into a paper, make the file executable, and also run it. Then, whenever you modify the file (its mtime attribute is changed), the application is immediately restarted. You deserve to try it by yourself: run the application, modify the file in a text editor, and after at a lot of 2 seconds, the application need to be restarted.


*
Bill
*
Petr Zemek
*
erm3nda

Hi. Once I make the python file executable I gained a brand-new error:

Traceearlier (many current call last): Documents "file.py", line 30, in os.execv(__file__, sys.argv)OSError: Exec format errorI’ve checked and tried some shebangs but nopoint works.

I don’t understand what os.execv(__file__, sys.argv) exacly does, however appears a popen up command also at all.This is what i did to relaunch the script:

def relaunch(): args = "" # should declare initially for i in sys.argv: args = args + " " + str(i) # pressure spreading to strings via str() to concatenate print "python" + args # print what would we run os.system("python" + args) # do it!Python script calling relaunch will certainly launch itself aacquire. I’m certain this solution do not cover memory managing or other elements, however I require the manuscript reloading at any kind of price :D


reboot. The other routine let’s me change the saved times (switch times) and also the names of the channels. Now, when I’m changing times or names, I save the new list via ‘pickle’ to a paper. When this file is adjusted, the switch-regimen restarts itself and reloads the pickle file to take on the new settings. I know, it’s sucount not the fine English style of coding, however it works flawlessly, that’s the crucial.

2 points to remark: First of all, your code runs flawlessly unter Python 3 as well. Just use

#!/usr/bin/python3as interpreter summary (I assume it is installed…). Secondly, you have the right to check every single file you desire. Just use

WATCHED_FILES = <"/home/user/.../nameofthemanuscript.py">Just for the beginners that don’t know – like me. (Trial and also error – method…) :)