Raspbian Service creation from python script

Not intended to be a tutorial, there are plenty of those with much better explanations than I can whip together out there on the nets. This is another page from my notebook of commands that I am endlessly re-Googling.

Create a unit file:

cd /lib/systemd/system/
sudo nano sample.service

...or, if you prefer vim, use could always use vi instead of nano

Fill it with:

[Unit]
Description=My Sample Service
After=multi-user.target

[Service]
Type=idle
ExecStart=/usr/bin/python3 /home/pi/sample.py

[Install]
WantedBy=multi-user.target

I'm assuming you are using / have installed python3
This is a very bare bones unit file, there is much more we can do with this, see at the bottom of this post

Set the permissions of sample.service:

sudo chmod 644 /lib/systemd/system/sample.service

Every time you make any kind of change to any unit file:

sudo systemctl daemon-reload

You must enable the service if you want it to start automatically on boot:

sudo systemctl enable sample.service

you will need repeat this action if/when you rename the service / init file

Reboot the Pi:

sudo reboot

Once a service has been installed:

sudo service <xyz> start
sudo service <xyz> stop
sudo service <xyz> restart
sudo service <xyz> status

all credit goes to:
https://www.dexterindustries.com/howto/run-a-program-on-your-raspberry-pi-at-startup/
https://github.com/torfsen/python-systemd-tutorial


That unit file, what else can we do with it?

Restart service on failure and run permissions

  • I want the service to restart automatically if the script crashes for any reason
  • If the script needs sudo permissions, we can run the service as root
[Unit]
Description=Simple explanation of Service
After=network.target

[Service]
Type=idle
SyslogIdentifier=SampleService
ExecStart=/usr/bin/python3 /home/pi/sample.py
Restart=on-failure
RestartSec=20
User=root
Group=root

[Install]
WantedBy=multi-user.target

Syslogging

I am currently (November 2019) leaving print statements in my python scripts that describe the actions executed, this helps help me identify exactly what is working and NOT working while I construct and run the script.

When we run the script as a service using systemd, these print statements do not appear in the terminal. Below are 2x ways we can inject these print statements into the system log.

method 1 - syslog function

Within the python script, import the syslog function from the syslog module, then anytime we want something to be printed to the syslog, we can.

from syslog import syslog
...
syslog(f"print string to the syslog, with {var1} and {var2}:")

In this example I am using f-String syntax for the string to be printed within the syslog
this is exactly the same as writing:

syslog("print string to the syslog, with " + str(var1) + " and " + str(var2) + ":")

method 2 - print to syslog

This is a less controllable solution, a more blunt approach.
Add the following to the init service file.

[Service]
...
StandardOutput=syslog
StandardError=syslog
Environment=PYTHONUNBUFFERED=1

The problem with this approach is that everything that would normally appear in the terminal output will be printed in the syslog, including stuff that you might not want to see in there.