Contents
Introduction
There are several ways to execute a piece of code when your Raspberry Pi boots. You can, for instance, use the nickname @reboot
in crontab
in order to launch an script after rebooting your machine. You can also configure crontab
to run the script every X minutes. However, if you want to create a Raspberry Pi service that runs at boot time, considers dependencies and keeps on running in the background, you should use systemd
.
Creating a Raspberry Pi service
Systemd
is an init system used in Linux distributions to bootstrap the user space and to manage system processes after booting. It includes a collection of tools for a range of different tasks. Its primary purpose is to initialise, manage and track system services and daemons, both during start-up and while the system is running.
Monitoring Raspberry temperature with a service
In this example we will create a service that monitors the Raspberry temperature. This service will send an IFTTT notification to the configured smartphone containing the Raspberry’s Pi temperature when this is greater than a certain value. We want to run this script automatically when booting the system, and let it running forever. This is the bash code of our script:
#/bin/bash maxTemp=65 minuteEnd=1 tag="tempMonitor" while true do GPUTemp=$(echo $(/opt/vc/bin/vcgencmd measure_temp) | egrep -o '[0-9]{2}.[0-9]{1}') CPUTemp=$(sed "s/\(...\)$/.\1/" < /sys/class/thermal/thermal_zone0/temp | egrep -o '[0-9]{2}.[0-9]{1}') if (( $(echo "$GPUTemp $maxTemp" | awk '{print ($1 > $2)}') )) || (( $(echo "$CPUTemp $maxTemp" | awk '{print ($1 > $2)}') )); then logger -t $tag "Sending alarm. CPU Temp: $CPUTemp. GPU Temp: $GPUTemp" curl -X POST -H "Content-Type: application/json" -d '{"value1":"'$CPUTemp'", "value2":"'$GPUTemp'"}' https://maker.ifttt.com/trigger/[YOUR_EVENT_NAME]/with/key/[YOUR_IFTTT_KEY] 2>1 fi loopWaitTime=$(( (((60 * (10 - ($(date +%-M) % 10))) + ((( minuteEnd * 60 )) - $(date +%-S))) % 300 ) )) sleep $loopWaitTime done
In order to know more about the IFTTT applets, read this post. I have used egrep
to extract the temperatures with one decimal and awk
to compare floating numbers. logger
is used to log the sent alarms, as well as the temperatures recorded, in the system log syslog
with the tag tempMonitor
. The script will sleep and wake up in the minutes ended in 1 or 6 (01, 06, 11, 16, etc.). To know more about how to calculate this sleep time, see the following post.
Creating a service
To convert the previous script into a service, start creating a .service
file with the following structure:
vi /home/dani/scripts/tempMonitor/tempMonitor.service [Unit] Description=Raspberry Temperature Monitor After=network-online.target [Service] ExecStart=/bin/bash /home/dani/scripts/tempMonitor/tempMonitor.sh WorkingDirectory=/home/dani/scripts/tempMonitor/ StandardOutput=inherit StandardError=inherit Restart=always User=dani [Install] WantedBy=multi-user.target
Just adapt the code to the path used in your system. The line After=network-online.target
will postpone the start of the service until the network is in up status. If you want to know more about some of the options used, I recommend you to read the following article.
Now copy the file into /lib/systemd/system
with root user:
sudo cp /home/dani/scripts/tempMonitor/tempMonitor.service /lib/systemd/system/
Testing the service
Once this has been copied, you can attempt to start the service using the following command:
sudo systemctl start tempMonitor.service
Check if it is running correctly by doing:
sudo systemctl status tempMonitor.service ● tempMonitor.service - Raspberry Temperature Monitor Loaded: loaded (/lib/systemd/system/tempMonitor.service; disabled) Active: active (running) since dom 2018-02-04 19:43:11 CET; 2s ago Main PID: 5709 (bash) CGroup: /system.slice/tempMonitor.service ├─5709 /bin/bash /home/dani/scripts/tempMonitor/tempMonitor.sh └─5728 sleep 300 feb 04 19:43:11 TrastoRaspberry systemd[1]: Started Raspberry Temperature Monitor.
Stop it using the following command:
sudo systemctl stop tempMonitor.service
And check again if the script is correctly stopped. Once everything is checked, you can configure your service to start automatically on reboot by using the following command:
sudo systemctl enable tempMonitor.service
From now on, you can check easier the status of the service by doing:
sudo service tempMonitor status/start/stop
Nice write up. Been searching most of the day on getting a script to run at bootup. Kept failing. Your instructions came up in a search and it worked.
Thanks for the cool description. Worded perfect for me.
I am getting this problem:
Active: failed (Result: exit-code) since Wed 2021-04-07 12:04:43 CDT; 16s ago
when I check the status after starting the service. Have you seen this before?
the examle script seems not to be up to date anymore, I’m getting errors starting it.
the path to vcgencmd does not exist, actual is /bin/vcgencmd
“<” now seems to be “<",
the > also causes error messages:
Feb 07 17:10:45 Medienserver bash[26739]: awk: 1: unexpected character '&'
Feb 07 17:10:45 Medienserver bash[26739]: awk: line 1: extra ')'
Feb 07 17:10:46 Medienserver bash[26742]: awk: 1: unexpected character '&'
Feb 07 17:10:46 Medienserver bash[26742]: awk: line 1: extra ')'
and calling man awk comes manual mawk, probably a newer version
dont get the script flying, but in general the article is good for understanding services