Cron — zaawansowany harmonogram zadań na serwerze
Opublikowano: 9 kwietnia 2026 · Kategoria: Administracja serwerem
Cron to standardowy daemon harmonogramowania zadań w systemach Linux — bez niego nie ma automatycznych backupów, aktualizacji certyfikatów SSL ani czyszczenia logów. Ten artykuł wykracza poza podstawy: poznasz zmienne środowiskowe, pułapki ścieżek, anacron oraz systemd timer jako nowoczesną alternatywę.
Składnia crontab — dokładne omówienie
Każda linia crontab ma 6 pól. Edytuj crontab przez crontab -e:
# Format: minuta godzina dzien_miesiaca miesiac dzien_tygodnia polecenie # 0-59 0-23 1-31 1-12 0-7 (0=7=Niedziela) # Codziennie o 3:00 — backup bazy danych 0 3 * * * /usr/bin/mysqldump -u root -p'haslo' baza > /backup/baza-$(date +\%Y\%m\%d).sql # Co 15 minut — sprawdzenie stanu aplikacji */15 * * * * /usr/bin/curl -s http://localhost/health > /dev/null # Co poniedziałek o 8:00 — tygodniowy raport 0 8 * * 1 /home/user/skrypty/tygodniowy-raport.sh # Pierwszego dnia miesiąca o 6:30 — czyszczenie logów 30 6 1 * * /usr/bin/find /var/log -name "*.gz" -mtime +30 -delete # Dwa razy dziennie (o 8:00 i 20:00) — synchronizacja danych 0 8,20 * * * /usr/local/bin/sync-dane.sh # Co godzinę w godzinach pracy (8-18) w dni powszednie 0 8-18 * * 1-5 /usr/local/bin/sprawdz-kolejke.sh
Specjalne wyrażenia — @daily, @weekly, @reboot
# Aliasy dla częstych harmonogramów @reboot /usr/local/bin/startuj-serwis.sh # Przy starcie systemu (raz) @hourly /skrypt.sh # Co godzinę (0 * * * *) @daily /skrypt.sh # Codziennie o północy (0 0 * * *) @weekly /skrypt.sh # W niedzielę o północy (0 0 * * 0) @monthly /skrypt.sh # 1. dnia miesiąca o północy (0 0 1 * *) @yearly /skrypt.sh # 1 stycznia o północy (0 0 1 1 *)
@reboot jest szczególnie przydatne do uruchamiania usług które nie mają init.d/systemd
unit — np. własne aplikacje Node.js lub skrypty inicjalizujące.
Zmienne środowiskowe i MAILTO
Cron uruchamia polecenia w minimalnym środowisku — brak ~/.bashrc, brak /usr/local/bin w PATH. Zawsze podawaj pełne ścieżki:
# Zmienne ustawione NA POCZĄTKU crontab (nie w bloku zadań) SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOME=/root # Powiadomienia email — output każdego zadania idzie na ten adres [email protected] # Wyłącz email (gdy nie chcesz powiadomień) # MAILTO="" # Teraz zadania z poprawnym PATH 0 3 * * * mysqldump -u root baza > /backup/baza.sql 0 4 * * * python3 /home/user/skrypt.py
Logowanie output zadań cron
# Przekieruj stdout i stderr do pliku logu z timestampem 0 3 * * * /skrypt.sh >> /var/log/moj-cron.log 2>&1 # Loguj z datą w nazwie pliku (rotacja dzienna) 0 3 * * * /skrypt.sh >> /var/log/cron-$(date +\%Y-\%m-\%d).log 2>&1 # Wyrzuć output (cichy tryb — tylko emaile przy błędzie) 0 3 * * * /skrypt.sh > /dev/null 2>&1 # Sprawdź logi systemowe cron grep CRON /var/log/syslog | tail -20 journalctl -u cron --since "1 hour ago"
Anacron — cron dla nieciągłych serwerów
Zwykły cron pomija zadania gdy serwer był wyłączony o zaplanowanej godzinie. Anacron rozwiązuje ten problem — uruchamia pominięte zadania przy następnym starcie:
# Instalacja anacron apt install anacron # Konfiguracja: /etc/anacrontab # Format: okres(dni) opóźnienie(min) identyfikator polecenie # Co dzień (min. co 24h od ostatniego uruchomienia), 5 min po starcie 1 5 backup.daily /usr/local/bin/backup-daily.sh # Co tydzień, 10 min po starcie systemu 7 10 cleanup.weekly /usr/local/bin/cleanup-weekly.sh # Co miesiąc, 15 min po starcie 30 15 report.monthly /usr/local/bin/raport-miesiac.sh
Anacron sprawdza w /var/spool/anacron/ kiedy zadanie ostatnio się wykonało. Jeśli
minął wymagany okres — uruchamia je po skonfigurowanym opóźnieniu (czas na pełny boot serwera).
Systemd Timer — nowoczesna alternatywa
Systemd timer to dwa pliki: .service (co robić) i .timer (kiedy). Przykład:
dzienny backup:
# /etc/systemd/system/backup-daily.service [Unit] Description=Dzienny backup bazy danych After=network.target mysql.service [Service] Type=oneshot User=backup ExecStart=/usr/local/bin/backup-daily.sh StandardOutput=journal StandardError=journal
# /etc/systemd/system/backup-daily.timer [Unit] Description=Uruchamiaj backup codziennie o 3:00 Requires=backup-daily.service [Timer] # Codziennie o 3:00 czasu lokalnego OnCalendar=*-*-* 03:00:00 # Uruchom jeśli pominięto (np. serwer był offline) Persistent=true # Losowe opóźnienie do 5 minut (rozłożenie obciążenia) RandomizedDelaySec=5min [Install] WantedBy=timers.target
# Aktywacja i zarządzanie timerem systemctl daemon-reload systemctl enable --now backup-daily.timer # Status i następne uruchomienie systemctl list-timers --all systemctl status backup-daily.timer # Logi zadania journalctl -u backup-daily.service --since "24 hours ago" # Uruchom ręcznie (testowanie) systemctl start backup-daily.service
Cron vs systemd timer — kiedy co wybrać
| Cecha | Cron | Systemd Timer |
|---|---|---|
| Prostota konfiguracji | Jeden plik, znana składnia | Dwa pliki, nowa składnia |
| Logi | Email lub plik ręcznie | Automatycznie w journald |
| Catch-up po restarcie | Nie (wymaga anacron) | Tak (Persistent=true) |
| Zależności między usługami | Brak | Pełna obsługa (After=, Wants=) |
| Timezone | System TZ lub CRON_TZ | OnCalendar z jawną strefą |
| Kiedy używać | Proste zadania, hosting współdzielony | VPS z systemd, złożone potoki |