Timery systemd zamiast crona: praktyczny przewodnik

Timer systemd to para jednostek. Plik .timer określa, kiedy uruchomić zadanie, a plik .service, co uruchomić. W porównaniu z cronem dostajesz logi w journalctl, nadrabianie uruchomień pominiętych podczas wyłączenia komputera dzięki Persistent=true oraz polecenie, które pokazuje, kiedy zadanie naprawdę wystartuje.

Opracowanie z użyciem narzędzi AI, na podstawie źródeł pierwotnych

Rysunek techniczny w stylu blueprint przedstawiający zazębione koła zębate mechanizmu zegarowego

Na większości współczesnych dystrybucji Linuksa systemd uruchamia usługi, a przy okazji potrafi też zastąpić crona. Opisane niżej opcje i polecenia pochodzą ze stron podręcznika systemd i działają tak samo w wersji 257 z Debiana 13 i w wersji 259 z Ubuntu 26.04 LTS.

1. Jak działa timer

Zadanie cyklicznie uruchamiane przez systemd składa się z dwóch plików. Plik .service opisuje, co uruchomić. Plik .timer z sekcją [Timer] opisuje, kiedy to zrobić. Timer domyślnie uruchamia usługę o tej samej nazwie bazowej, więc kopia.timer steruje kopia.service.

Włączasz timer, a nie usługę. Dlatego sekcję [Install] z wpisem WantedBy=timers.target ma plik .timer. Usługa uruchamiana przez timer jej nie potrzebuje.

2. Pierwszy timer krok po kroku

Zacznij od usługi. Dla zadań, które coś robią i kończą pracę, systemd.service(5) przewiduje typ oneshot. Menedżer uznaje wtedy uruchomienie za zakończone dopiero, gdy proces skończy pracę.

# /etc/systemd/system/kopia.service
[Unit]
Description=Nocna kopia katalogu /srv

[Service]
Type=oneshot
ExecStart=/usr/local/bin/kopia.sh

Teraz timer, który uruchomi usługę codziennie o 3:00:

# /etc/systemd/system/kopia.timer
[Unit]
Description=Codzienna kopia o 3:00

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target

Po utworzeniu plików przeładuj konfigurację i włącz timer. Opcja --now od razu go aktywuje.

sudo systemctl daemon-reload
sudo systemctl enable --now kopia.timer

3. OnCalendar: składnia i przeliczanie wpisów crona

systemd.time(7) opisuje wyrażenia kalendarzowe w postaci DzieńTygodnia Rok-Miesiąc-Dzień Godzina:Minuta:Sekunda. Każde pole może być gwiazdką, wartością, listą po przecinku, zakresem z .. albo wartością z krokiem po /. Dzień tygodnia i data są opcjonalne, więc samo 08:05:40 oznacza codziennie o tej godzinie. Opcję OnCalendar= możesz podać kilka razy w jednym timerze.

Wpis crona 0 3 * * * to *-*-* 03:00:00, a 30 6 * * 1-5 to Mon..Fri *-*-* 06:30:00. Są też skróty, na przykład hourly (*-*-* *:00:00), daily (*-*-* 00:00:00), weekly (Mon *-*-* 00:00:00) i monthly (*-*-01 00:00:00). Z tej samej składni korzystają harmonogramy kopii zapasowych w Proxmox VE.

4. Sprawdzanie harmonogramu

Zanim włączysz timer, sprawdź wyrażenie. systemd-analyze(1) opisuje polecenie systemd-analyze calendar, które normalizuje wyrażenie i pokazuje najbliższe uruchomienie. Opcja --iterations= wyświetla kolejne terminy.

systemd-analyze calendar --iterations=3 'Mon..Fri *-*-* 06:30:00'

W wyniku zobaczysz formę znormalizowaną (Normalized form), najbliższy termin (Next elapse) i czas do niego (From now). Działające timery pokazuje systemctl list-timers. Kolumny NEXT i LEFT mówią, kiedy nastąpi następne uruchomienie. LAST i PASSED mówią, kiedy było ostatnie. ACTIVATES wskazuje usługę uruchamianą przez timer.

5. Timery monotoniczne

Nie każde zadanie jest związane z godziną. systemd.timer(5) opisuje timery liczone od zdarzeń. OnBootSec= liczy czas od uruchomienia systemu, OnStartupSec= od startu menedżera usług, OnActiveSec= od aktywacji timera, a OnUnitActiveSec= od ostatniego uruchomienia usługi.

[Timer]
OnBootSec=15min
OnUnitActiveSec=1w

Ten timer uruchomi usługę 15 minut po starcie systemu, a potem co tydzień, licząc od poprzedniego uruchomienia. W przeciwieństwie do OnCalendar= taki harmonogram nie zależy od zegara systemowego.

6. Persistent, RandomizedDelaySec i AccuracySec

Persistent=true zapisuje na dysku czas ostatniego uruchomienia. Jeśli komputer był wyłączony w chwili planowanego uruchomienia, usługa wystartuje zaraz po włączeniu. Opcja działa tylko z OnCalendar=, a jej wartość domyślna to false. Cron sam tego nie robi, dlatego do tej roli powstał osobny program anacron.

RandomizedDelaySec= opóźnia uruchomienie o losowy czas od zera do podanej wartości, domyślnie 0. Rozkłada to w czasie zadania wielu maszyn ustawionych na tę samą godzinę. AccuracySec= określa okno dokładności, domyślnie 1 minutę. systemd uruchamia timer w wybranym punkcie tego okna, co pozwala grupować wybudzenia. Jeśli zadanie musi ruszyć co do sekundy, ustaw AccuracySec=1s.

7. Logi i ręczne uruchamianie

Wyjście zadania trafia do dziennika systemd. Pokażesz je poleceniem journalctl -u kopia.service, które journalctl(1) opisuje jako filtr po jednostce. Dziennik samego timera wyświetli journalctl -u kopia.timer.

Żeby przetestować zadanie bez czekania na harmonogram, uruchom usługę poleceniem sudo systemctl start kopia.service. Timer nie zmieni przy tym swojego harmonogramu. Jednorazowe zadanie bez tworzenia plików zaplanujesz przez systemd-run(1). Na przykład systemd-run --on-calendar='*-*-* 22:00:00' /usr/local/bin/raport.sh tworzy tymczasowy timer, który zniknie po restarcie systemu.

8. Timery użytkownika i lingering

Zwykły użytkownik może mieć własne timery. Pliki umieszcza w ~/.config/systemd/user/, a zarządza nimi przez systemctl --user, które komunikuje się z menedżerem usług tego użytkownika. Logi pokazuje journalctl --user -u nazwa.service. Według podręcznika działa to tylko przy trwałym zapisie dziennika, ustawianym opcją Storage= w journald.conf.

Menedżer usług użytkownika normalnie działa tylko wtedy, gdy użytkownik jest zalogowany. Polecenie loginctl enable-linger nazwa_użytkownika sprawia, że według loginctl(1) menedżer startuje razem z systemem i działa po wylogowaniu. Bez tego timer użytkownika nie uruchomi się na serwerze, na który nikt się nie loguje.

9. Czego timery nie robią tak jak cron

Cron wysyła wyjście zadania e-mailem na adres ze zmiennej MAILTO. systemd.timer(5) nie ma takiej opcji. Wyjście trafia do dziennika i tam je sprawdzasz, a powiadomienia o błędach musisz zbudować osobno. Za to opis zadania wymaga dwóch plików zamiast jednej linii w crontabie.

Jeśli masz wiele istniejących zadań crona, Debian oferuje pakiet systemd-cron. Tłumaczy on na bieżąco /etc/crontab, pliki z /etc/cron.d i katalogów cron.daily i pokrewnych oraz crontaby użytkowników na jednostki .timer i .service.

10. Podsumowanie

Timer systemd to cron z dodatkami, czyli logami w dzienniku, nadrabianiem pominiętych uruchomień, losowym opóźnieniem i timerami liczonymi od startu systemu. Przed włączeniem timera sprawdź wyrażenie przez systemd-analyze calendar. Po włączeniu kontroluj systemctl list-timers i journalctl -u. Jedyną realną stratą w porównaniu z cronem jest brak wbudowanych powiadomień e-mail.

Najczęstsze pytania

Jak przenieść wpis 0 3 * * * na OnCalendar?

Wpis crona oznaczający codziennie o 3:00 zapisujesz jako OnCalendar=*-*-* 03:00:00, a w skrócie OnCalendar=03:00, bo część z datą jest opcjonalna. Wynik sprawdzisz poleceniem systemd-analyze calendar, które pokaże najbliższe uruchomienie.

Jak uruchomić zadanie od razu, bez czekania na timer?

Uruchom usługę, a nie timer, poleceniem systemctl start nazwa.service. Usługa wykona się natychmiast, a harmonogram timera pozostanie bez zmian.

Czy timery systemd wysyłają e-mail przy błędzie?

Nie tak jak cron. Strona podręcznika systemd.timer nie ma odpowiednika zmiennej MAILTO. Wynik zadania sprawdzasz w dzienniku poleceniem journalctl, a powiadomienia musisz zorganizować osobno.

Źródła

  1. systemd.timer(5), systemd (2026)
  2. systemd.time(7), systemd (2026)
  3. systemd.service(5), systemd (2026)
  4. systemctl(1), systemd (2026)
  5. systemd-run(1), systemd (2026)
  6. systemd-analyze(1), systemd (2026)
  7. journalctl(1), systemd (2026)
  8. loginctl(1), systemd (2026)
  9. systemd-cron, Debian Wiki (2026)
  10. Details of package systemd in trixie, Debian (2026)
  11. Ubuntu 26.04 LTS, summary for LTS users, Canonical (2026)

O autorze

Rafał Lesiński na co dzień zajmuje się administracją systemów i wsparciem IT dla małych firm. Pracuje z serwerami Linux (Debian, Ubuntu Server) i Windows Server, platformą Microsoft Azure oraz usługami Microsoft 365, w tym Entra ID, Teams i SharePoint Online. Zajmuje się też monitoringiem i bezpieczeństwem infrastruktury (Zabbix, Wazuh, Microsoft Sentinel) oraz wirtualizacją i automatyzacją (Proxmox VE, Hyper-V, Docker, Ansible). Programuje w Pythonie i PHP (Laravel). Prowadzi serwis Wybryki Informatyki, w którym każdy artykuł opiera się na dokumentacji i źródłach pierwotnych.

Niezbędne (zawsze włączone). Pamięć przeglądarki przechowuje wybrany motyw, polubione artykuły i Twoją decyzję o zgodzie. Nie używamy do tego plików cookies.