Create a target unit
First create a .target
unit; this will act as our synchronization point. For this example, let's create daily-task.target
:
[Unit]
Description=Run daily tasks
Create daily task services
For services that run in parallel, create Type=oneshot
service units that (a) are RequiredBy=daily-task.target
and (b) Run Before=daily-task.target
. For example:
example1.service
[Unit]
Before=daily-task.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'sleep 10; date > /tmp/example1.txt'
[Install]
RequiredBy=daily-task.target
example2.service
[Unit]
Before=daily-task.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'sleep 15; date > /tmp/example2.txt'
[Install]
RequiredBy=daily-task.target
Create post-task services
For services that should run after everything is complete, create
service units that (a) are RequiredBy=daily-task.target
, and that
(b) run After=daily-task.target
. For example:
example3.service:
[Unit]
Description=Run after all daily tasks are complete
After=daily-task.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'sleep 10; date > /tmp/example3.txt'
ExecStopPost=/sbin/systemctl --no-block --user stop daily-tasks.target
[Install]
RequiredBy=daily-task.target
We run systemctl stop daily-task.target
in this task (via an
ExecStopPost
hook) in order to move the target into a "stopped"
state; if we don't do this, then next time we try to systemctl start daily-task.target
nothing will happen, because the target is already
started.
Enable your services
systemctl --user enable example{1,2,3}.service
Start the target
To run our daily tasks, we start the target:
systemctl --user start daily-tasks.target
If you are watching your logs when this happens, you will see:
Sep 06 17:44:19 hostname systemd[5435]: Starting example1.service...
Sep 06 17:44:19 hostname systemd[5435]: Starting example2.service...
Sep 06 17:44:29 hostname systemd[5435]: Finished example1.service.
Sep 06 17:44:34 hostname systemd[5435]: Finished example2.service.
Sep 06 17:44:34 hostname systemd[5435]: Reached target Start daily tasks.
Sep 06 17:44:34 hostname systemd[5435]: Starting example3.service...
Sep 06 17:44:44 hostname systemd[5435]: Stopped target Start daily tasks.
Sep 06 17:44:44 hostname systemd[5435]: Finished example3.service.
Due to the dependencies we have created combined with our use of
Type=oneshot
services, example1
and example2
run
before daily-tasks.target
is considered "started", and example3
runs once everything else is complete.