Rozwiązywanie problemów z Cron: Dlaczego twoje zadania się nie uruchamiają
Zadania cron, które cicho zawodzą, są frustrujące i częste. Ten systematyczny przewodnik rozwiązywania problemów przeprowadzi przez najczęstsze problemy i ich rozwiązania, pomagając ci niezawodnie uruchomić zaplanowane zadania.
Najpierw sprawdź podstawy
Zanim zagłębisz się w złożone debugowanie, sprawdź podstawy. Wiele problemów z cron wynika z prostych przeoczień, które łatwo zweryfikować.
Najpierw potwierdź, że twój crontab został faktycznie zapisany. Po edycji za pomocą "crontab -e" sprawdź go za pomocą "crontab -l", aby wyświetlić swój crontab. Jeśli twoje wpisy się nie pojawiają, nie zostały zapisane. Typowe przyczyny: zamknięcie edytora bez zapisania, złe konto użytkownika (crontab jest per użytkownik) lub błędy składni powodujące odrzucenie crontab.
Sprawdź, czy demon cron działa. W większości systemów Linux użyj "systemctl status cron" lub "systemctl status crond" (nazwa demona różni się w zależności od dystrybucji). Jeśli cron nie działa, twoje zadania nie mogą być wykonywane. Uruchom go za pomocą "systemctl start cron" lub "service cron start".
Sprawdź, czy twoja składnia cron jest poprawna. Użyj naszego generatora crontab, aby zwalidować swoje wyrażenie i zobaczyć, kiedy się uruchomi. Prosta literówka jak "0 0 * * 8" (nie ma dnia 8) lub "60 0 * * *" (minuta 60 nie istnieje) powoduje ciche błędy. Demon cron często nie zgłasza błędów składni jasno.
Sprawdź logi systemowe pod kątem wykonania cron. W systemach systemd użyj "journalctl -u cron" lub "journalctl -u crond". W starszych systemach sprawdź /var/log/syslog lub /var/log/cron. Te logi pokazują, kiedy cron uruchamia zadania, nawet jeśli samo zadanie zawodzi. Jeśli nie widzisz, że twoje zadanie się uruchamia, problem jest w planowaniu cron. Jeśli widzisz, że się uruchamia, ale zawodzi, problem jest w twoim poleceniu.
Potwierdź, że edytujesz właściwy crontab użytkownika. Zadania cron uruchamiają się jako użytkownik, do którego należy crontab. Jeśli potrzebujesz uprawnień root, użyj "sudo crontab -e", aby edytować crontab roota, nie crontab twojego użytkownika. Uruchomienie "crontab -e" jako zwykły użytkownik, a następnie próba uruchomienia poleceń wymagających uprawnień root, zakończy się błędami uprawnień.
Upewnij się, że twoje polecenie istnieje i jest wykonywalne. Z terminala uruchom ręcznie dokładne polecenie z crontab. Jeśli zawodzi interaktywnie, na pewno zawiedzie w cron. Jeśli się powiedzie interaktywnie, ale zawodzi w cron, problem prawdopodobnie leży w różnicach środowiska (omówione dalej).
Problemy ze środowiskiem i ścieżkami
Najczęstszym powodem, dla którego zadania cron zawodzą, są różnice środowiskowe między twoją interaktywną powłoką a minimalnym środowiskiem cron. Gdy uruchamiasz polecenia z terminala, twoja powłoka zapewnia rozbudowaną konfigurację: PATH z lokalizacjami do znajdowania plików wykonywalnych, zmienne środowiskowe z .bashrc lub .profile, katalog roboczy ustawiony na twój katalog domowy lub projektowy oraz ustawienia języka/lokalizacji. Cron nie zapewnia prawie nic z tego.
PATH cron jest typowo tylko "/usr/bin:/bin", co oznacza, że może znaleźć pliki wykonywalne tylko w tych dwóch katalogach. Jeśli twój skrypt jest w /home/user/bin, cron go nie znajdzie. Jeśli twoje zadanie używa "python", a python jest w /usr/local/bin lub virtualenv, cron nie może go znaleźć. Zawsze używaj ścieżek bezwzględnych: "/usr/bin/python3" zamiast "python3", "/home/user/scripts/backup.sh" zamiast "backup.sh".
Zmienne środowiskowe, na których polegasz, nie istnieją w cron. DATABASE_URL, API_KEYS, poświadczenia AWS i inne zmienne z twojego .bashrc nie są dostępne. Ustaw je jawnie w samym crontab (na górze, przed liniami zadań: "DATABASE_URL=...") lub w swoim skrypcie. Alternatywnie, źródłuj plik środowiska: ". /home/user/.env && /home/user/script.sh".
Katalog roboczy jest nieprzewidywalny w cron - często katalog domowy użytkownika, ale nie gwarantowany. Jeśli twój skrypt wykonuje "open('config.json')" i oczekuje lokalnego pliku, zawiedzie, gdy zostanie uruchomiony z innego katalogu. Używaj ścieżek bezwzględnych dla wszystkich operacji na plikach lub jawnie przejdź do potrzebnego katalogu: "cd /home/user/project && ./script.sh".
Aby debugować problemy środowiskowe, utwórz testowe zadanie cron, które wypisuje środowisko: "* * * * * env > /tmp/cron-env.txt". Pozwól mu się uruchomić, poczekaj minutę, a następnie zbadaj /tmp/cron-env.txt, aby zobaczyć dokładnie, jakie środowisko zapewnia cron. Porównaj to z "env" w twojej interaktywnej powłoce, aby zobaczyć, czego brakuje.
Dla projektów Python aktywuj virtualenv jawnie: "*/5 * * * * cd /path/to/project && /path/to/venv/bin/python script.py". Plik binarny Python virtualenv zawiera konfigurację środowiska. Podobnie dla Node.js, Ruby lub innych środowisk specyficznych dla języka.
Problemy z lokalizacją powodują subtelne błędy. Cron może działać z lokalizacją "POSIX", podczas gdy twoje środowisko deweloperskie używa "en_US.UTF-8". To wpływa na sortowanie ciągów, parsowanie dat i kodowanie znaków. Ustaw lokalizację jawnie, jeśli potrzeba: "LC_ALL=en_US.UTF-8 /path/to/script".
Rozważ utworzenie skryptu opakowującego, który spójnie konfiguruje środowisko, a następnie wywołuje twój rzeczywisty skrypt. Opakowanie źródłuje pliki środowiska, ustawia PATH, przechodzi do właściwego katalogu i obsługuje wspólną konfigurację. To centralizuje konfigurację środowiska, zamiast powtarzać ją w każdym wpisie crontab.
Logowanie i wyjście
Błędy zadań cron są trudne do debugowania bez wyjścia. Domyślnie cron wysyła wyjście poleceń i błędy e-mailem do użytkownika, ale większość nowoczesnych systemów nie ma skonfigurowanej lokalnej poczty e-mail, więc to wyjście znika. Jawne logowanie rozwiązuje ten problem.
Przekieruj stdout i stderr do pliku logu: "0 2 * * * /path/to/script.sh > /var/log/myjob.log 2>&1". "> /var/log/myjob.log" przekierowuje standardowe wyjście (stdout) do pliku. "2>&1" przekierowuje standardowy błąd (stderr) tam, gdzie idzie stdout (plik logu). Teraz wszystkie wyjście, włącznie z komunikatami o błędach, trafia do pliku, który możesz zbadać, gdy twoje zadanie zawiedzie.
Dopisuj zamiast nadpisywać, aby budować historię: "0 2 * * * /path/to/script.sh >> /var/log/myjob.log 2>&1". ">>" dopisuje do pliku zamiast go zastępować. Każde uruchomienie dodaje do logu, tworząc historię. Uważaj na wzrost pliku logu - zaimplementuj rotację logów lub okresowe czyszczenie.
Dodaj znaczniki czasu, aby rozróżniać uruchomienia: W swoim skrypcie użyj "date", aby wypisać, kiedy się uruchamia. Lub użyj biblioteki logowania, która automatycznie dodaje znaczniki czasu do wpisów. Bez znaczników czasu trudno powiedzieć, które wpisy logu pochodzą z którego wykonania.
Rotacja logów zapobiega nieograniczonemu wzrostowi. Użyj logrotate, aby automatycznie archiwizować, kompresować i usuwać stare logi. Utwórz /etc/logrotate.d/myjob z konfiguracją, aby rotować logi zadania cron co tydzień lub gdy osiągną określony rozmiar.
Dla krytycznych zadań rozważ zarówno logowanie do pliku, jak i alarmowanie przy błędzie. Przechwyć wyjście do logu, a następnie sprawdź kod wyjścia: "0 2 * * * /path/to/script.sh >> /var/log/myjob.log 2>&1 || echo 'Zadanie nieudane' | mail -s 'Błąd Cron' [email protected]". "||" oznacza "lub" - jeśli skrypt zawiedzie (kod wyjścia niezerowy), wyślij e-mail.
Oddziel stdout i stderr, jeśli musisz rozróżniać normalne wyjście od błędów: "0 2 * * * /path/to/script.sh >> /var/log/myjob.out 2>> /var/log/myjob.err". Teraz normalne wyjście trafia do .out, a błędy do .err.
Do testowania użyj krótkiego interwału (co 2 minuty) i często sprawdzaj logi: "*/2 * * * * /path/to/script.sh >> /tmp/test.log 2>&1". Gdy zadziała, zmień na harmonogram produkcyjny i przenieś logi do właściwej lokalizacji.
Pamiętaj, że cron bez przekierowania próbuje wysłać wyjście e-mailem. Jeśli twój system generuje lokalną pocztę e-mail (sprawdź /var/mail/nazwa_użytkownika), możesz tam znaleźć wyjście. Ale jawne logowanie jest bardziej niezawodne niż poleganie na lokalnej poczcie e-mail.
Wypróbuj Narzędzie
Crontab Generator
Powiązane Artykuły
Składnia Cron wyjaśniona
Pięciopolowa składnia cron jest zwodniczo prosta, ale niesamowicie potężna. Ten przewodnik rozkłada każde pole, każdy znak specjalny i zasady określające, jak się łączą, aby tworzyć harmonogramy od 'co minutę' do 'drugi wtorek nieparzystych miesięcy o 3:47'.
Przykłady i przypadki użycia Crontab
Teoria jest ważna, ale zobaczenie wyrażeń cron w kontekście z rzeczywistymi przypadkami użycia sprawia, że składnia staje się zrozumiała. Ta kolekcja obejmuje najczęstsze scenariusze planowania, z którymi się spotkasz, od prostej automatyzacji po złożone harmonogramy produkcyjne.