Skrypt działa bezbłędnie, gdy wpiszesz jego nazwę. Zaplanowany w crontab nie robi nic: żadnego pliku kopii zapasowej, żadnego e-maila, żadnego błędu. Zadanie cron, które nie działa, to jedna z najczęstszych drobnych zagadek w administracji Linuksem, a przyczyną prawie nigdy nie jest sam cron. To różnica między Twoją interaktywną powłoką a gołym środowiskiem, które cron daje każdemu zadaniu. Oto zwykłe przyczyny, w kolejności wartej sprawdzenia, i sposób budowania zaplanowanych zadań, którym naprawdę można ufać.
1. Zadanie cron nie działa? Zacznij od środowiska
Cron uruchamia zadania z minimalnym środowiskiem. Nie czyta .bashrc ani .profile, a domyślny PATH w cron to tylko /usr/bin:/bin. Polecenie w /usr/local/bin lub /usr/sbin albo narzędzie zainstalowane tylko dla Twojego użytkownika po prostu nie zostanie znalezione. Zmienne środowiskowe cron to także krótka lista: hasło do bazy wyeksportowane w profilu, ustawienie proxy lub języka, na których polegasz interaktywnie, tam nie będą dostępne.
Poprawki: używaj pełnych ścieżek poleceń w skrypcie, ustaw PATH na początku crontab lub skryptu i ładuj każdą potrzebną konfigurację z pliku, który skrypt czyta jawnie. Aby zobaczyć dokładnie, co daje cron, zaplanuj jednorazowe zadanie, które zapisuje wynik env do pliku w /tmp, i porównaj go ze swoją powłoką.
2. Zadanie działa pod sh, a nie Bash
Jeśli crontab nie ustawia SHELL, cron uruchamia każdy wiersz poleceń przez /bin/sh. W Debianie i Ubuntu jest to dash, mniejsza powłoka, która nie rozumie funkcji Bash, takich jak tablice, testy w podwójnych nawiasach kwadratowych czy polecenie source. Zacznij każdy skrypt od wiersza #!/bin/bash, nadaj mu prawo wykonywania i wywołuj skrypt z crona zamiast wklejać do crontab długie jednolinijkowce Bash.
3. Crontab nie działa z powodu samego pliku
- Znak procenta. W wierszu polecenia crontab cron zamienia nieescapowany znak procenta na nową linię. Klasyczną ofiarą jest format daty przekazany bezpośrednio poleceniu date. Zabezpiecz każdy ukośnikiem wstecznym albo przenieś polecenie do skryptu.
- Ostatni wiersz. Crontab wymaga nowej linii po ostatnim wpisie, inaczej ten wpis może zostać zignorowany.
- Pole użytkownika. Wpisy w /etc/crontab i /etc/cron.d zawierają nazwę użytkownika między harmonogramem a poleceniem; osobiste crontaby edytowane przez crontab -e nie. Pomylenie tych dwóch formatów psuje wpis.
- Nazwy plików w katalogach cron. W systemach opartych na Debianie skrypty w /etc/cron.daily i podobnych folderach uruchamia run-parts, który pomija nazwy plików zawierające kropkę. Skrypt o nazwie backup.sh umieszczony tam nigdy się nie uruchomi; nazwij go backup. Pliki w /etc/cron.d podlegają tej samej regule nazewnictwa.
- Uprawnienia. Skrypty w tych folderach muszą być wykonywalne, a skrypt należący do jednego użytkownika może nie być czytelny dla konta, z którego działa zadanie.
4. Zadanie się uruchomiło, tylko nie wtedy, kiedy oczekiwano
Cron kieruje się strefą czasową serwera. Wiele serwerów w chmurze działa w UTC, więc zadanie przewidziane na 2 w nocy w Los Angeles uruchamia się naprawdę wczesnym wieczorem czasu pacyficznego, a różnica przesuwa się o godzinę, gdy zaczyna się lub kończy czas letni. Sprawdź ustawienie przez timedatectl, a potem zapisz harmonogram w strefie serwera albo świadomie zmień strefę. W zadaniach związanych z godzinami pracy firmy zanotuj strefę czasową w komentarzu obok wpisu.
5. Zadanie się uruchomiło i cicho zawiodło: gdzie szukać logów cron
Domyślnie cron wysyła wynik zadania e-mailem do jego właściciela, co trafia donikąd na serwerach bez dostarczania poczty. W obecnych Debianie i Ubuntu usługa cron zapisuje każde uruchomione zadanie w dzienniku systemd, więc journalctl -u cron pokazuje, czy zadanie w ogóle zostało uruchomione. Debian 12 i nowsze nie instalują już domyślnie rsyslog, dlatego /var/log/syslog może nie istnieć, gdy szukasz logów cron. Jeśli zadanie zostało uruchomione, ale nie wytworzyło niczego użytecznego, przekieruj jego wyjście do pliku logu albo ustaw MAILTO na adres, który ktoś czyta, i niech skrypt sam zgłasza swoje błędy.
Jak sprawić, by zaplanowane zadania były godne zaufania
Gdy zadanie już działa, kilka nawyków sprawia, że działa dalej. To one odróżniają skrypty powłoki na zamówienie, o których można zapomnieć, od takich, które cicho zawodzą przez miesiące, i to zasady stojące za naszą pracą nad skryptami Bash i automatyzacją:
- Tryb ścisły. set -euo pipefail sprawia, że skrypt zatrzymuje się na pierwszym nieudanym poleceniu zamiast kontynuować z brakującymi danymi.
- Brak nakładających się uruchomień. Opakowanie zadania w flock -n z plikiem blokady oznacza, że wolne uruchomienie jest pomijane, a nie podwajane, gdy zaczyna się następne.
- Sygnał życia. Zadanie zgłasza sukces do kontroli monitoringu po zakończeniu; jeśli zgłoszenie nie nadejdzie, ktoś dostaje alert.
- Timery systemd dla cięższych zadań. Timery systemd zapisują logi w dzienniku, potrafią nadrobić uruchomienia pominięte, gdy serwer był wyłączony, dzięki Persistent=true, i pokazują ostatnie oraz następne uruchomienie w systemctl list-timers.
Najczęściej zadawane pytania: zadanie cron nie działa
Jak przetestować zadanie cron bez czekania na harmonogram?
Uruchom je z tym samym gołym środowiskiem: env -i z minimalnym PATH, jako ten sam użytkownik i przez /bin/sh, jeśli tego używa cron. Jeśli tak działa, zadziała też z crona. Sprawdza się też zaplanowanie go na każdą minutę na krótki czas i obserwowanie dziennika.
Dlaczego moje zadanie cron uruchamia się dwa razy?
Zwykle dlatego, że jest zaplanowane w dwóch miejscach, na przykład w osobistym crontab i w /etc/cron.d, albo dlatego, że poprzednie uruchomienie jeszcze trwało, gdy zaczęło się następne. Sprawdź crontab -l dla każdego użytkownika oraz /etc/crontab i /etc/cron.d, i dodaj blokadę przez flock.
Dlaczego moje zadanie działa z crontab -e, ale nie z /etc/cron.d?
Prawie zawsze chodzi o pole użytkownika lub nazwę pliku. Wpisy w /etc/cron.d potrzebują kolumny użytkownika, a nazwa pliku z kropką jest ignorowana.
Masz dość skryptów, które działają tylko wtedy, gdy ktoś patrzy? Nasza usługa skryptów Bash i automatyzacji na zamówienie pisze, testuje i dokumentuje zaplanowane zadania dla kopii zapasowych, wdrożeń i kontroli stanu, a nasze usługi skryptów Bash obejmują też naprawę skryptów napisanych przez kogoś innego. W sprawie usług automatyzacji Linux w Los Angeles i Long Beach skontaktuj się z nami, krótko opisując zadanie i serwer, na którym działa.




