Artykuł Serwery

Cron w Linux - jak ustawić zadania cykliczne (crontab)

Cron to demon Linuksa, który uruchamia zadania o zaplanowanym czasie. Zadania definiujesz komendą crontab -e w składni pięciu pól - minuta, godzina, dzień miesiąca, miesiąc, dzień tygodnia - plus polecenie. Przykład: 0 3 * * * /home/user/backup.sh uruchamia backup codziennie o 3:00.

W skrócie: cron to najprostszy sposób na automatyzację powtarzalnej roboty na serwerze - backupów, czyszczenia logów, odpytywania API, synchronizacji plików. Poniżej rozkładam składnię crontab na czynniki pierwsze, pokazuję gotowe wyrażenia do skopiowania i tłumaczę, dlaczego zadanie, które działa w terminalu, potrafi milczeć w cronie.

Czym jest cron, crond i crontab

Trzy słowa, które początkujący myli, a które oznaczają różne rzeczy:

  • cron - koncept i sama usługa harmonogramowania zadań w systemach z rodziny Unix. To ona pilnuje zegara i odpala polecenia o zaplanowanym czasie.
  • crond - demon, czyli proces działający w tle, który realnie wykonuje cron. To on co minutę sprawdza, czy jest coś do uruchomienia.
  • crontab - i plik konfiguracyjny (cron table), i komenda do jego edycji. W pliku trzymasz listę zadań, komendą crontab nim zarządzasz.

Konkret: cron obsługuje zadania cykliczne, powtarzane co minutę, godzinę, dzień czy miesiąc. Jeśli potrzebujesz uruchomić coś jednorazowo o konkretnej porze, do tego służy osobne polecenie at - cron jest od rytmu, nie od pojedynczego strzału. Najpopularniejsze odmiany demona to Vixie cron (standard w większości dystrybucji) oraz fcron.

Sporo systemowych narzędzi opiera się na cronie po cichu - logrotate rotujący logi, Logwatch raportujący zdarzenia czy Rootkit Hunter skanujący system korzystają właśnie z tej usługi. Gdy więc uczysz się crona, uczysz się mechaniki, którą serwer i tak już wykorzystuje pod maską.

Składnia crontab - pięć pól

Sedno całej sprawy. Każda linia crontaba to pięć pól czasu plus polecenie do uruchomienia. Kolejność jest stała:

Pole Zakres Znaczenie
1. minuta 0-59 minuta godziny
2. godzina 0-23 godzina doby (format 24h)
3. dzień miesiąca 1-31 dzień miesiąca
4. miesiąc 1-12 miesiąc (1 = styczeń)
5. dzień tygodnia 0-7 0 i 7 = niedziela, 1 = poniedziałek

Za tymi pięcioma polami wpisujesz polecenie. Całość czyta się jak zdanie: "o tej minucie, tej godziny, tego dnia - wykonaj to".

Operatory - jak opisać powtarzalność

Pola nie muszą zawierać jednej liczby. Masz cztery operatory:

  • * - każda wartość ("dowolna minuta", "dowolny dzień").
  • , - lista wartości, np. 0,30 w polu minut oznacza minutę 0 i 30.
  • - - zakres, np. 1-5 w polu dnia tygodnia to od poniedziałku do piątku.
  • / - krok, np. */5 w polu minut to co pięć minut.

Konkret: */5 * * * * znaczy "co pięć minut, przez całą dobę, każdego dnia". Ta czwórka operatorów pokrywa 95% realnych potrzeb.

Skróty - @reboot, @daily i reszta

Zamiast pięciu pól możesz użyć gotowego skrótu. Są czytelniejsze i trudniej się w nich pomylić:

  • @reboot - raz, przy każdym starcie systemu.
  • @hourly - co godzinę (równoważne 0 * * * *).
  • @daily - codziennie o północy (0 0 * * *).
  • @weekly - co tydzień, w niedzielę o północy.
  • @monthly - pierwszego dnia miesiąca o północy.
  • @yearly - raz do roku, 1 stycznia.

Pro tip admina: zanim wkleisz wyrażenie do crontaba, przetestuj je na sucho w kalkulatorze składni crontab.guru - wpisujesz pięć pól, a strona pokazuje po angielsku, kiedy zadanie się odpali. Oszczędza to godziny zgadywania, dlaczego backup ruszył o złej porze.

Jak dodać zadanie krok po kroku

Krok po kroku, na crontabie bieżącego użytkownika:

  1. Otwórz swój crontab poleceniem crontab -e. Przy pierwszym uruchomieniu system zapyta o edytor - do wyboru zwykle Nano, Vim albo Vi. Jeśli dopiero łączysz się z serwerem, żeby to zrobić, zacznij od podstaw pracy przez połączenie SSH z serwerem.

Sprawdź: crontabu nie edytujesz nigdy ręcznie w katalogu spool (/var/spool/cron/). Zawsze przez crontab -e - komenda pilnuje składni i przeładowania. Grzebanie w pliku spool na piechotę to prosta droga do zadania, które cicho nie działa.

Gotowe wyrażenia cron - tabela do skopiowania

Zestaw wyrażeń, które w praktyce pokrywają większość zadań admina:

Wyrażenie Kiedy się uruchamia Typowe zastosowanie
* * * * * co minutę health-check, kolejka zadań
*/15 * * * * co 15 minut odpytywanie API, monitoring
0 2 * * * codziennie o 2:00 backup bazy danych
0 0 * * 0 w każdą niedzielę o północy rotacja logów, raport tygodniowy
30 4 1 * * 1. dnia miesiąca o 4:30 raport miesięczny, fakturowanie
0 */6 * * * co 6 godzin synchronizacja plików, cache
@reboot po każdym starcie serwera montowanie zasobów, start usługi

Konkret: dwa najczęstsze scenariusze w praktyce to backup i monitoring. Backup przez cron najczęściej spina się z narzędziem rsync do przyrostowej synchronizacji, a w cronie wygląda to tak: */15 * * * * curl -fsS https://moja-strona.pl/health || echo "down".

Crontab użytkownika vs crontab systemowy

Cron ma dwa światy i warto je rozróżnić, bo zadania trafiają w różne miejsca.

Crontab użytkownika to ten, który edytujesz przez crontab -e. Każdy użytkownik, łącznie z rootem, ma własny. Zadania działają z uprawnieniami tego użytkownika, a pliki leżą w katalogu spool (/var/spool/cron/ lub /var/spool/cron/crontabs/, zależnie od dystrybucji). Nie podajesz w nim, na jakim koncie ma działać zadanie - dziedziczy Twoje.

Crontab systemowy to plik /etc/crontab oraz osobne pliki wrzucane do katalogu /etc/cron.d/. Różnica jest jedna, ale istotna: w składni dochodzi szóste pole - nazwa użytkownika, z którego uprawnieniami zadanie ma się wykonać. To miejsce na zadania utrzymania systemu, a nie na drobne skrypty pojedynczego konta.

Obok tego działają katalogi uruchamiane automatycznie: /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly i /etc/cron.monthly. Wrzucasz do nich wykonywalny skrypt (bez żadnej składni czasu), a mechanizm run-parts odpala wszystko z danego katalogu w zaplanowanym cyklu. Wygodne, gdy nie zależy Ci na dokładnej godzinie, tylko na rytmie "raz dziennie".

Dostęp do crona reguluje para plików /etc/cron.allow i /etc/cron.deny - decydują, którzy użytkownicy w ogóle mogą zakładać zadania. Na współdzielonym serwerze to pierwsze miejsce do sprawdzenia, gdy crontab -e odmawia współpracy.

Najczęstsze błędy i pułapki

Większość problemów z cronem to nie awarie demona, tylko powtarzalne potknięcia. Oto te, które łapią najczęściej:

  • PATH - cron startuje z minimalnym środowiskiem. Polecenie, które śmiga w Twoim shellu, w cronie potrafi zwrócić "command not found", bo brakuje mu ścieżek. Rozwiązanie: używaj pełnych ścieżek (/usr/bin/rsync, nie rsync) albo ustaw PATH=... na górze crontaba.
  • Ścieżki względne - cron uruchamia zadanie z katalogu domowego użytkownika, nie z lokalizacji skryptu. Jeśli skrypt odwołuje się do plików "obok siebie", w cronie ich nie znajdzie. Podawaj ścieżki bezwzględne.
  • Brak uprawnień wykonania - skrypt bez chmod +x albo bez linii shebang (#!/bin/bash) nie ruszy. Pułapka: w terminalu odpalasz bash skrypt.sh i działa, a cron próbuje wykonać plik wprost.
  • Znak procenta - w crontabie % ma specjalne znaczenie (oznacza znak nowej linii). Jeśli polecenie zawiera procent, np. w formacie daty date +%Y, trzeba go escapować jako \%.
  • Brak logowania - domyślnie cron nie pokazuje błędów na ekranie. Zawsze przekierowuj wyjście do pliku: dopisz >> /var/log/mojcron.log 2>&1 na końcu linii, a zapiszesz i standardowe wyjście, i błędy.
  • Strefa czasowa - cron działa według czasu systemowego serwera, nie Twojego lokalnego. Zanim uznasz, że zadanie ruszyło o złej porze, sprawdź date i timedatectl na maszynie.

Jak debugować zadanie, które się nie uruchamia

Zadanie milczy, a Ty nie wiesz dlaczego. Krok po kroku, od najczęstszej przyczyny:

  1. Sprawdź, czy demon żyje. Na Debianie i Ubuntu: systemctl status cron. Na RHEL, Rocky i AlmaLinux usługa nazywa się inaczej: systemctl status crond. Jeśli demon nie działa, żadne zadanie nie ruszy.
  2. Zajrzyj do logów. Cron zapisuje każde uruchomienie. Na Debianie i Ubuntu: grep CRON /var/log/syslog albo journalctl -u cron. Na RHEL: /var/log/cron. W logu zobaczysz, czy cron w ogóle próbował odpalić zadanie, czy nie widzi go wcale.
  3. Odróżnij dwa przypadki. Jeśli w logu jest wpis uruchomienia, ale polecenie nie zadziałało - problem jest w skrypcie (PATH, ścieżki, uprawnienia). Jeśli wpisu nie ma - problem jest w składni crontaba albo demon nie działa.
  4. Przetestuj polecenie w czystym środowisku. Cron nie ma Twoich zmiennych - odtwórz to lokalnie komendą env -i /bin/bash -c 'twoje-polecenie'. Jeśli tu też się sypie, wiesz, że winne jest środowisko, nie cron.
  5. Włącz powiadomienia mailem. Zmienna MAILTO="ty@example.com" na górze crontaba sprawia, że cron wyśle na maila wyjście każdego zadania. Szybka droga do zobaczenia realnego komunikatu błędu.

anacron i systemd timer - kiedy zamiast crona

Cron ma jedno założenie: maszyna działa non stop. Jeśli serwer śpi o 2:00, zadanie zaplanowane na tę godzinę po prostu przepada - cron go nie nadrobi. Stąd dwie alternatywy warte znajomości.

anacron rozwiązuje właśnie problem pominiętych zadań. Zamiast konkretnej godziny operuje częstotliwością w dniach i pilnuje, kiedy zadanie ostatnio się wykonało (konfiguracja w /etc/anacrontab). Gdy maszyna była wyłączona o zaplanowanej porze, anacron uruchomi zadanie zaraz po starcie. To dlatego na laptopach i stacjach roboczych cykliczne zadania utrzymania często stoją na anacronie, nie na czystym cronie.

systemd timer to nowocześniejsza alternatywa na dystrybucjach z systemd. Zamiast jednej linii w crontabie definiujesz parę plików: .service (co uruchomić) i .timer (kiedy). Trade-off: więcej pisania na start, ale w zamian dostajesz zależności między usługami, dokładne logowanie w journalctl i elastyczny harmonogram (OnCalendar) z nadrabianiem pominięć jak w anacronie. Do prostego "backup co noc" cron nadal wygrywa prostotą - do złożonych zależności między zadaniami sensowniejszy bywa timer.

Cron ma sens dopiero na stale działającym serwerze

Konkret: cron uruchamia zadanie tylko wtedy, gdy maszyna jest włączona. Nocny backup na własnym laptopie się nie wykona, bo o 3:00 sprzęt śpi. Automatyzacja przez cron zaczyna mieć sens dopiero na serwerze, który chodzi 24 godziny na dobę - dlatego backupy, synchronizacje i monitoring naturalnie lądują na VPS albo hostingu z dostępem do powłoki.

To zależy od ruchu: jeśli dopiero dobierasz serwer pod automatyzację i cykliczne zadania, sprawdź porównanie VPS pod zadania DevOps - dobierzesz maszynę pod realne obciążenie, bez przepłacania za zasoby, których nie wykorzystasz. A kto chce wejść głębiej w administrację serwerem i automatyzację, dobrze zaczyna od solidnych podstaw pracy w powłoce, do których cron jest naturalnym kolejnym krokiem.

FAQ

Jak wyświetlić listę zadań cron?

Zadania bieżącego użytkownika pokaże crontab -l. Dla innego użytkownika: sudo crontab -u nazwa -l. Zadania systemowe zobaczysz osobno - podejrzyj cat /etc/crontab oraz zawartość katalogu ls /etc/cron.d/. To dwa różne światy, więc żeby mieć pełny obraz, sprawdź oba źródła.

Jak ustawić zadanie cron co minutę?

Wyrażenie * * * * * uruchamia polecenie co minutę, przez całą dobę, każdego dnia. Pięć gwiazdek oznacza "dowolna minuta, godzina, dzień, miesiąc i dzień tygodnia". To najkrótszy możliwy interwał czystego crona - jeśli potrzebujesz częściej niż raz na minutę, cron nie wystarczy i sięgasz po pętlę w skrypcie albo systemd timer.

Gdzie są logi crona w Linux?

Zależnie od dystrybucji. Na Debianie i Ubuntu zajrzyj do /var/log/syslog i filtruj po cronie: grep CRON /var/log/syslog, albo użyj journalctl -u cron. Na RHEL, Rocky i AlmaLinux logi trafiają do /var/log/cron. W logu widać każdą próbę uruchomienia zadania - to pierwsze miejsce przy diagnozie.

Dlaczego moje zadanie cron się nie uruchamia?

Najczęstsze przyczyny to zły PATH (cron ma minimalne środowisko), ścieżki względne zamiast bezwzględnych, brak uprawnień wykonania skryptu lub literówka w składni. Przekieruj wyjście do pliku poleceniem >> /var/log/mojcron.log 2>&1 i sprawdź logi crona - z realnym komunikatem błędu diagnoza zajmuje minutę.

Czym różni się cron od anacron i systemd timer?

Cron wymaga, by maszyna działała w zaplanowanym momencie - pominięte zadania przepadają. Anacron nadrabia zadania pominięte przez wyłączenie maszyny, operując częstotliwością w dniach. Systemd timer to nowoczesna alternatywa z lepszym logowaniem w journalctl i zależnościami między usługami. Do prostych zadań cyklicznych cron nadal wygrywa prostotą.

Jak edytować crontab innego użytkownika?

Z uprawnieniami roota użyj sudo crontab -u nazwa_uzytkownika -e. Otworzy to crontab wskazanego konta, a zadania wykonają się z jego uprawnieniami. To standard przy zadaniach serwera WWW, które powinny działać jako www-data, a nie jako root - mniejsze uprawnienia to mniejsze ryzyko przy błędzie w skrypcie.