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

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
- systemd.timer(5), systemd (2026)
- systemd.time(7), systemd (2026)
- systemd.service(5), systemd (2026)
- systemctl(1), systemd (2026)
- systemd-run(1), systemd (2026)
- systemd-analyze(1), systemd (2026)
- journalctl(1), systemd (2026)
- loginctl(1), systemd (2026)
- systemd-cron, Debian Wiki (2026)
- Details of package systemd in trixie, Debian (2026)
- Ubuntu 26.04 LTS, summary for LTS users, Canonical (2026)



