1

I want to prevent multiple python scripts from crashing on my Raspberry Pi (Stretch OS).

I wanted to clarify if this would be the way of implementing a systemd file to prevent multiple python scripts from crashing. Under the service section of the service file, the typical format is:

[Service]
ExecStart=/path/too/script
Restart=always

But since I am running multiple python scripts, I think I should add python to the front of the path, as well as stacking service section on top of each other. Please correct me if I am wrong.

My current script (constantrun.service) is:

[Unit]
Description='python scripts that needs to be run constantly'

[Service]
ExecStart=python /home/pi/projects/script1.py
Restart=always
[Service]
ExecStart=python /home/pi/projects/script2.py
Restart=always
[Service]
ExecStart=python /home/pi/projects/script3.py
Restart=always

[Install]
WantedBy=multi-user.target

However, when I run try to start this service file with sudo systemctl start constantrun.service. I get the following error:

Failed to start constantrun.service: Unit constantrun.service is not loaded properly: Invalid argument.
See system logs and 'systemctl status constantrun.service' for details.

I open the log, and I see:

● constantrun.service - 'python scripts that needs to be run constantly'
   Loaded: error (Reason: Invalid argument)
   Active: inactive (dead)

Feb 18 17:15:12 raspberrypi systemd[1]: [/lib/systemd/system/constantrun.service:11] Executable path is not absolute, ignoring: python /home/pi/P
Feb 18 17:15:12 raspberrypi systemd[1]: constantrun.service: Service lacks both ExecStart= and ExecStop= setting. Refusing.
Feb 18 17:20:17 raspberrypi systemd[1]: [/lib/systemd/system/constantrun.service:5] Executable path is not absolute, ignoring: python /home/pi/Pr
Feb 18 17:20:17 raspberrypi systemd[1]: [/lib/systemd/system/constantrun.service:8] Executable path is not absolute, ignoring: python /home/pi/Pr
Feb 18 17:20:17 raspberrypi systemd[1]: [/lib/systemd/system/constantrun.service:11] Executable path is not absolute, ignoring: python /home/pi/P
Feb 18 17:20:17 raspberrypi systemd[1]: constantrun.service: Service lacks both ExecStart= and ExecStop= setting. Refusing.
Feb 18 17:20:33 raspberrypi systemd[1]: [/lib/systemd/system/constantrun.service:5] Executable path is not absolute, ignoring: python /home/pi/Pr
Feb 18 17:20:33 raspberrypi systemd[1]: [/lib/systemd/system/constantrun.service:8] Executable path is not absolute, ignoring: python /home/pi/Pr
Feb 18 17:20:33 raspberrypi systemd[1]: [/lib/systemd/system/constantrun.service:11] Executable path is not absolute, ignoring: python /home/pi/P
Feb 18 17:20:33 raspberrypi systemd[1]: constantrun.service: Service lacks both ExecStart= and ExecStop= setting. Refusing.

How can I modify the code above to get it working? Also, do I need to add a path to my python library such asPYTHONPATH=/home/pi/.local/lib/python2.7/site-packages?

I am really new to the linux environment, and would appreciate any advice on this!

  • 1
    The best way to prevent a script from crashing is to not let it crash in the first place. What do you want to achieve here? – pfnuesel Feb 18 '18 at 6:25
  • @pfnuesel: I have two python scripts that read/write a text file. Most of the time, they work fine simultaneously. However, occasionally, either one of them can crash, and I think that is because one is writing while the other is reading the text file. This only occurs when the read/write processes from both scripts coincide, which is not very often. Hence, I thought of trying an approach so that either python scripts can still pick itself up and continue running even after such an error. – Craver2000 Feb 18 '18 at 6:44
  • 1
    @Craver2000, if I understand you correctly, one script is a producer and one is a consumer. Is this correct, or do they communicate between each other? Are there any other dependencies between the two scripts? If it's a strict producer/consumer relationship, piping the output from one to the other might be a better solution. – ErikF Feb 18 '18 at 9:59
  • 1
    @Craver2000 in that case, I would suggest using a file lock while you're writing to the file. It's less prone to failure! – ErikF Feb 18 '18 at 11:01
  • 2
    I agree with the commenters above that you should fix the synchronization problem in your scripts, and not try to sweep them under the carpet using systemd. Having said that, what systemd is complaining about is that you haven't specified an absolute path to the python interpreter in the unit file. The absolute path to the script is not enough, you need the path to the python binary as well, something like /usr/bin/python. – Johan Myréen Feb 18 '18 at 11:28
0

Your service definitions are like this:

[Service]
ExecStart=python /home/pi/projects/script1.py
Restart=always

And this is the error message on each of them:

Executable path is not absolute, ignoring: python /home/pi/...

For systemd, the "executable" in this service definition is python, and that is clearly not an absolute path. The /home/pi/projects/script1.py is just an argument to this python executable, and caring about its proper form is the executable's job.

Any Python-specific environment variables like PYTHONPATH have no meaning at all for systemd: you must give it an absolute path for the executable in the service definition, each and every time.

Typically, the absolute path to the python interpreter is /usr/bin/python, but you can check:

$ type python
python is /usr/bin/python

So your service definitions should be like this:

[Service]
ExecStart=/usr/bin/python /home/pi/projects/script1.py
Restart=always

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.