Setting up a simple systemd timer
I’ll keep this short, for my app KOU Cafeteria, I had written a simple Python script which retrives and parses cafeteria menu from schools website. The script worked and still works fine but there was one slight problem. I had to call the script the first thing every month, and sometimes I forgot that and it made me lose a lot of users. Also one time the school changed the menu but the app didn’t so.. (ciao more users). But I had enough, I knew I had to set up a cron job but I knew nothing about them (tried to set one but couldn’t) so I thought learning how systemd timers work wouldbe a good idea.
I’ll write here what I did to set up a timer correctly
Write a shell script
First thing one should do (this is the same for cron jobs) is to write a shell script which calls your python script with the absolute path. Something like this:
/usr/bin/python3 /home/ali/path/to/my/script.py
In your scripts, prepend every file with their absolute names or they won’t work.
Set up a systemd service
Go to /etc/systemd/system/
and create your a file called myscript.service
. In it one should write:
[Unit]
Description=A short description for your script or service
[Service]
ExecStart=/bin/bash /home/ali/path/to/your/script.sh
Description is pretty self-explanatory and ExecStart tells the service what should it do to start the service. Here we tell that it should run our .sh file with bash
.
Important thing to note here is that you should prepend your scripts path with /bin/bash
or your service won’t work.
Now that you created your service it’s time to enable it. Enter
sudo systemctl enable myscript.service
Create a .timer file
Now for the last step, in that same directory we need to create a .timer file. Create a file called myscript.timer and enter this in it:
[Unit]
Description=Runs script every 60 seconds
[Timer]
# Time to wait after booting before we run first time
OnBootSec=10min
# Time between running each consecutive time
OnUnitActiveSec=60
Unit=myscript.service
[Install]
WantedBy=multi-user.target
Again [unit] is self-explanatory, important part here is [timer] part. OnBootSec sets how much the service should wait after system has been booted. OnUnitActiveSec sets script should be called every x seconds. x here is 60, I want my script to run every minute, that’s how you do it with systemd timers. Unit defines which unit file should run after timer fires.
After having done that you need to enable and start your service:
sudo systemctl enable myscript.timer
sudo systemctl start myscript.timer