I'll try to describe how I created a timer. The timer works without a problem for a long time.
I need periodically run a bash script, which sets certain states for Nvidia Optimus card. The bash script loads and unloads bbswitch module with certain parameters. The module is contained in the bbswitch package.
The script is executed periodically, using systemd timer. Four main steps in creating a timer are:
- Create a bash script to run:
bbswitch.sh
- Create a systemd service:
bbswitch.service
- Create a systemd timer:
bbswitch.timer
- Enable a systemd timer
- (Optional) Start a systemd timer
Bash script
I called the script bbswitch.sh, and placed it in the /opt folder. The script may be placed in any folder you wish. The script actually does some job with Nvidia Optimus card.
The content of /opt/bbswitch.sh is:
#!/bin/bash
#==2014.01.30
#--
#--this job is run by
#--systemd timer every
#--15 seconds.
#--
#--it silents nvidia
#--cooling fans, by
#--switching nvidia
#--card on-off with
#--bbswitch.
#--
#==
sudo rmmod bbswitch
sudo modprobe bbswitch load_state=1
sudo cat /proc/acpi/bbswitch
sudo rmmod bbswitch
sudo modprobe bbswitch load_state=0
sudo cat /proc/acpi/bbswitch
exit 0
The bash script may containt any commands you wish to run. It is not limited in any way.
Systemd service
Systemd service file bbswitch.service must be placed in the /etc/systemd/system folder.
The content of /etc/systemd/system/bbswitch.service is:
[Unit]
Description=bbswitch
[Service]
Type=oneshot
ExecStart=/opt/bbswitch.sh
WorkingDirectory=/tmp
Note two things:
Description= filed must be the same as service and timer names - bbswitch in this example
ExecStart= field must point to the script to be executed and it must be fully qualified file name, i.e. the file name with the full path
Systemd timer
Systemd timer file bbswitch.timer must be placed in the /etc/systemd/system folder as well. In other words, in the same folder as bbswitch.service file.
I scheduled the timer to be triggered every 15 seconds. In other words, every 15 seconds it triggers bbswitch.service, which, in turn, runs /opt/bbswitch.sh script.
The content of /etc/systemd/system/bbswitch.timer is:
[Unit]
Description=bbswitch
[Timer]
OnCalendar=*:*:00,15,30,45
#--OnCalendar=minutely
#--OnCalendar=*:0/1
#--OnCalendar=*:0/5
#--OnCalendar=*:0/10
#--OnCalendar=*:0/15
#--OnCalendar=yyyy-mm-dd hh:mm:ss
#--OnCalendar=*:00,05,10,15,20,25,30,35,40,45,55:*
Persistent=true
[Install]
WantedBy=timers.target
Two notes:
Description= field must be the same as service and timer names - bbswitch in this example
OnCalendar=*:*:00,15,30,45 instruction triggers the bbswitch.timer every 15 seconds. Other valid OnCalendar timestamp examples are included and commented out
The timer is triggered according to the timestampt, used in the OnCalendar= instruction. There's an endless number of possible timestamps, recognized by systemd. It's impossible to describe them all here.
To verify whether or not a particuler timestampt is valid and recognized by systemd, use the command:
systemd-analyze calendar [timestamp]
Enable systemd timer
This is trivial:
sudo systemctl enable bbswitch.timer
There is no need to explicitly enable bbswitch.service.
(Optional) Start systemd timer
Once bbswitch.timer has been enabled - in the step above - the timer will start automatically on the next boot up.
If you don't want to wait until reboot, the timer may be started by hand with:
sudo systemctl start bbswitch.timer
Check timer's state
Despite of the timer qualifier, bbswitch.timer is a systemd service. The current status of both bbswitch.timer and bbswitch.service may be checked with the usual command:
systemctl status bbswitch.timer
systemctl status bbswitch.service
The regular status for bbswitch.timer is:
$ systemctl status bbswitch.timer
● bbswitch.timer - bbswitch
Loaded: loaded (/etc/systemd/system/bbswitch.timer; enabled; vendor preset>
Active: active (waiting) since Mon 2020-08-03 21:44:03 MSK; 1h 9min ago
Trigger: Mon 2020-08-03 22:53:00 MSK; 12s ago
Triggers: ● bbswitch.service
Note the active (waiting) state for the timer. It waits to be triggered the next time. The last time it was triggered 12 seconds ago in this example.
The regular status for bbswitch.service is:
$ systemctl status bbswitch.service
● bbswitch.service - bbswitch
Loaded: loaded (/etc/systemd/system/bbswitch.service; static; vendor preset: enabled)
Active: inactive (dead) since Mon 2020-08-03 23:06:33 MSK; 8s ago
TriggeredBy: ● bbswitch.timer
Process: 8381 ExecStart=/opt/bbswitch.sh (code=exited, status=0/SUCCESS)
Main PID: 8381 (code=exited, status=0/SUCCESS)
Don't worry about Active: inactive (dead) service state. This is normal. The service was triggered by bbswitched.timer 8 seconds ago, ran /opt/bbswitch.sh script, and is now dead waiting to be triggered again by bbswitch.timer. The service is going alive for a fractions of second, needed to launch /opt/bbswitch.sh. The service is dead during other 15 seconds.
That's all.