Ugly plans to control the time
Once upon time there were cronjobs, now there are systemd timers with a lot of new features.
I will not go deep on systemd, only few notes
To create a simple timer we need to create:
- a script to run something
- a service to start the script execution
- a timer to schedule the service
Create a very very useless script
we will create a simple script that for out test purposes will only create a file.
#!/bin/bash
DATE=$(date +%s)
touch /tmp/$DATE
Create a Systemd Unit Service
What is a Systemd unit?
The systemd unit basically is the smallest entity of Systemd, there are a lot of different unit types.
We are interested in only 2 types
- Service
- A service ( suffix
.service
) unit contains information about process which are to be managed by systemd. - Timer
- A Timer ( suffix
.timer
) unit and can control service execution (scheduling).
Each unit resites in a file in one of these locations:
- /lib/systemd/system
- system default unit files
- /etc/systemd/system
- user-defined unit files and modifications of installed software units
- /usr/lib/systemd/system
- unit files for installed software
To view all unit files.
# all units
systemctl list-unit-files
# Only Service units
systemctl list-unit-files --type service
# Only Timer units
systemctl list-unit-files --type timer
A service unit has different sections, for our purpose we need only 2[Unit]
contains metadata, a [Service]
contains actions to be executed and a [Install]
section.
The [Install]
section is used to define the commands to be executed unit is enable disable.
We will use only one field, which is WantedBy=multi-user.target
.
If systemctl enable testTimer.timer or testTimer.service is executed then the timer/service will be attached to multi-user.target.
The target
refers to a group of related processes, it is like the old init runlevel.
The a targes is reached all the units inside will be started.
When we run the systemctl enable/disabled command, a symbolic link is created/removed inside the multi-user.target.wants directory
. For this service we do not need [Install]
section.
Create a file named testTimer.service
in /etc/systemd/system
[Unit]
Description= A very simple Timer
Wants=testTimer.timer
[Service]
ExecStart=/bin/bash /aboslute/path/to/script.sh
# ExecStartPre: commands to be executed before ExecStart
# ExecStart: commands to be executed where systemctl start is called
# ExecStartPost: commands to be executed after ExecStart
# ExecStop: commands to be run when systemctl stop is called
# ExecReload: commands to be run when systemctl reload is called
# ExecStopPost: commands to be executed after ExecStop automatically
# ....
# ....
Create a Systemd timer
Create a file named testTimer.timer
in /etc/systemd/system
[Unit]
Description=Timer to be executed ever 2 minutes
Requires=testTimer.service
[Timer]
# every 2 minutes
OnUnitActiveSec=10
Unit=testTimer.service
[Install]
WantedBy=multi-user.target
You can notice the presence of the same section name [Unit]
with metadata, then now we have the [Timer]
section
Timer | Definition | is Monmotonic? |
---|---|---|
OnActiveSec | relative to timer activation | yes |
OnBootSec | relative to OS boot | yes |
OnStartupSec | realtive to sysmted service | yes |
OnUnitActiveSec | relative to last activation of the timer | yes |
OnUnitInactiveSec | relative to last deactivation of the timer | yes |
OnCalendar | on exact caledar date time | no |
A monolitic timer is stopped when the system is suspended and it is not persistent between reboots.
Run
sudo systemctl enable testTimer.timer
sudo systemctl start testTimer.timer
sudo systemctl status testTimer.timer