A Service and Its Timer

First the service

Write the work as an ordinary oneshot service — a job that runs and finishes. This one just appends a line to a file:

sudo tee /etc/systemd/system/report.service > /dev/null <<'EOF'
[Unit]
Description=Write a report

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'date >> /var/tmp/report.log'
EOF
cat /etc/systemd/system/report.service

In the terminal

student@vulntech:~$ sudo tee /etc/systemd/system/report.service > /dev/null <<'EOF'
> [Unit]
> Description=Write a report
> 
> [Service]
> Type=oneshot
> ExecStart=/bin/sh -c 'date >> /var/tmp/report.log'
> EOF
[sudo] password for student:
student@vulntech:~$ cat /etc/systemd/system/report.service
[Unit]
Description=Write a report

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'date >> /var/tmp/report.log'

Then the timer

The timer has a [Timer] section with the schedule and an [Install] section pointing at timers.target so it starts at boot. OnUnitActiveSec=1h means “one hour after each run”; OnCalendar (next lesson) gives clock times:

sudo tee /etc/systemd/system/report.timer > /dev/null <<'EOF'
[Unit]
Description=Run report hourly

[Timer]
OnCalendar=hourly
Persistent=true

[Install]
WantedBy=timers.target
EOF
cat /etc/systemd/system/report.timer

In the terminal

student@vulntech:~$ sudo tee /etc/systemd/system/report.timer > /dev/null <<'EOF'
> [Unit]
> Description=Run report hourly
> 
> [Timer]
> OnCalendar=hourly
> Persistent=true
> 
> [Install]
> WantedBy=timers.target
> EOF
[sudo] password for student:
student@vulntech:~$ cat /etc/systemd/system/report.timer
[Unit]
Description=Run report hourly

[Timer]
OnCalendar=hourly
Persistent=true

[Install]
WantedBy=timers.target

Enable the timer, not the service

You start and enable the timer — the service is left alone, because the timer starts it on schedule. enable --now turns it on now and at boot:

sudo systemctl daemon-reload
sudo systemctl enable --now report.timer
systemctl is-active report.timer
systemctl list-timers report.timer --no-pager

In the terminal

student@vulntech:~$ sudo systemctl daemon-reload
[sudo] password for student:
student@vulntech:~$ sudo systemctl enable --now report.timer
Created symlink /etc/systemd/system/timers.target.wants/report.timer → /etc/systemd/system/report.timer.
student@vulntech:~$ systemctl is-active report.timer
active
student@vulntech:~$ systemctl list-timers report.timer --no-pager
NEXT                        LEFT       LAST PASSED UNIT         ACTIVATES
Sun 2026-10-18 08:00:00 UTC 58min left -    -      report.timer report.service

1 timers listed.
Pass --all to see loaded but inactive timers, too.

Common mistake: Enable the .timer, not the .service. If you enable the service it runs once at boot and never again; the timer is what makes it repeat on schedule.

Remember: A scheduled job is a oneshot service plus a .timer with a [Timer] schedule and WantedBy=timers.target. daemon-reload, then enable --now the.timer.

HOME LEARN COMMUNITY DASHBOARD
Practice terminal Starting…