Cron - wszystko w swoim czasie

Archiwalne, stare wpisy FAQ i HowTo Użytkowników
RaV.
Posty: 87
Rejestracja: 28 czerwca 2006, 15:30
Lokalizacja: 127.0.0.1

Cron - wszystko w swoim czasie

Post autor: RaV. »

Zacznijmy, tak pro-forma, od tego czym jest Cron. Ów tajemniczy Cron jest demonem, który co minutę budzi się z głębokiego snu, żeby sprawdzić, czy nie ma czegoś do roboty. Przegląda tablice użytkowników oraz tablice systemowe w poszukiwaniu poleceń, które zostały zaplanowane do wykonania w danej minucie. Nie najgorszym porównaniem, dla tych co dopiero chcieliby poznać system Linusa Torvaldsa, a do tej pory pracowali z systemami z Redmond, jest windowsowy Scheduler (Harmonogram zadań).

Cron korzysta z dwóch typów tablic. Tablic użytkowników, którymi to tablicami zajmiemy się wpierw, oraz tablicy systemowej, o której chwilę później, gdyż jest jedynie drobną modyfikacją tablicy użytkowników.

Domyślnie w Debianie, z Crona korzystać może każdy z użytkowników, jednak może się zdarzyć, że kogoś nie lubimy i chcielibyśmy wyłączyć mu możliwość zabawy tym użytecznym narzędziem. Odpowiedzialność za przywilej korzystania z demona zadań biorą na siebie dwa pliki: /etc/cron.allow oraz /etc/cron.deny. Jeśli tych plików brak, wszyscy mogą korzystać z Crona. Możemy zezwolić tylko niektórym użytkownikom na korzystanie z narzędzia umieszczając jego login w pliku allow. Istnieje także możliwość zabronienia tylko niektórym poprzez stworzenie pliku deny i umieszczenie tam ich loginów.

Skoro już mamy możliwość pracy z Cronem, warto przejść od teorii do praktyki i... Jeszcze większej ilości teorii. Do pracy z tablicami wykorzystujemy narzędzie o dźwięcznie brzmiącej nazwie crontab, który posiada kilka przełączników:
-e - edycja tablicy
-l - drukowanie tablicy na ekran (listing)
-r - wysłanie tablicy w kosmos, czyli jej usunięcie. przy używaniu tego przełącznika proponuję się trzy razy zastanowić, gdyż skasowanie tablicy Crona z kilkunastoma wpisami, których odtworzenie może zająć sporo czasu, może skutkować uzmysłowieniem sobie, jak bardzo nasze słownictwo bogate jest w wulgaryzmy.

Przejdźmy zatem do kolejnej porcji teorii, czyli jaki format ma nasza tablica. Składa się ona z pięciu pól, mówiących kiedy oraz szóstego informującego co należy wykonać. Pola są odseparowane od siebie co najmniej jednym znakiem spacji lub tabulatora. "Co najmniej" oznacza, ze może być ich więcej i często dla poprawy czytelności pliku, stosuje się ich większą ilość. Długość szóstego pola, pola polecenia jest nieograniczona co do długości. Możliwe jest tam więc wpisanie nawet dość zaawansowanego skryptu powłoki. Jedynym warunkiem jest tu to, że musi to być w jednej linii. O ile prosty skrypt nie jest tak strasznie złym pomysłem, to jednak nawet drobna korekta dłuższego skryptu może doprowadzić, nawet najbardziej zagorzałego fana "jednolinijkowców" do rozstroju żołądka.

Skoro już co nieco wiemy o ostatnim polu, powiedzmy sobie jeszcze słówko o pierwszych pięciu. Podręcznik systemowy dość dobrze je opisuje, więc pozwolę sobie na "studencką" metodę ich opisania:

Kod: Zaznacz cały

              Pole           dozwolone wartości
              -----          --------------
              minuta         0-59
              godzina        0-23
              dzień miesiąca 1-31
              miesiąc        1-12
              dzień tygodnia 0-7 (0 lub 7 jest niedzielą)
... Z małą modyfikacją, ponieważ do przetłumaczonej, na nasz ojczysty język, wersji podręcznika, wkradł się błąd, który mówi o dopuszczeniu wartości "0" (zero) w polu dni miesiąca i samym miesiącu. Co jest oczywiście bzdurą. Jednak dzień tygodnia może przyjąć tę wartość i zarówno zero jak i siedem oznaczają niedzielę. Po to, by uszczęśliwić tym drobnym gestem zarówno tych, którzy uważają, że tydzień zaczyna się od tego dnia jak i tych, którzy twierdzą, że jednak niedziela kończy tydzień.

Z grubsza, pola mogą przyjmować następujące (przykładowe) wartości: "*", "1-5", "*/3", "6,9", które oznaczają kolejno "dla każdego", "od-do", "co któryś" i listę wartości. Pomiędzy wszystkimi polami jest operator AND, który mówi, że WSZYSTKIE pola muszą się zgadzać.

Przy pracy z Cronem warto pamiętać, że jedna linijka to jedno zadanie. W jednej tablicy możemy umieścić wiele zadań. Warto czasem też poszczególne zadania opatrzyć komentarzem, który dodajemy, umieszczając komentarz w osobnej linii i rozpoczynając go znakiem "hash" ("#"). Komentarze są o tyle istotne, że pozwalają na szybkie zorientowanie się, w jakim celu został utworzony konkretny wpis. O ile w przypadku dwóch, trzech zadań, może się to wydać zbędne, tak jeśli mówimy o kilkunastu, to w ich gąszczu dość łatwo się zgubić.

Polecenie zawarte w ostatnim polu zostanie wykonane z prawami użytkownika, do którego należy tablica. A co się wydarzy, gdy polecenie generuje komunikaty na STDOUT lub STDERR? Zostaną skierowane do skrzynki pocztowej użytkownika. I tu dochodzimy do jeszcze jednej ważnej sprawie, o której należałoby wspomnieć. Zmienne. Gdybyśmy chcieli zmienić adresata treści, które zamiast na ekranie lądują nam w skrzynce odbiorczej, musielibyśmy ustawić zmienną MAILTO="docelowy_uzytkownik", która wskaże odbiorcę całego tego "spamu". Możemy także ustawić pustą zmienną (MAILTO=""), wówczas komunikaty nie zostaną wysłane "nigdzie". Tym samym poruszyliśmy kwestię zmiennych wykorzystywanych przez Crona. Część jest ustawianych automatycznie. Część nie. Warto o tym pamiętać przy wywoływaniu zewnętrznych poleceń, gdyż podczas pracy z powłoką systemową możemy mieć ustawioną zmienną $PATH a w niej ścieżkę "~/bin". Zakładając, że w tym katalogu znajduje się plik wykonywalny "prog", możemy go wywołać z dowolnego miejsca w systemie wpisując ciąg znaków "prog" w linii poleceń. Kiedy spróbujemy w tablicy Crona dokonać tej samej sztuczki, możemy poczuć pewien dyskomfort psychiczny, zastanawiając się czemu "prog" się nie wykonuje. powodem tej sytuacji jest zapewne fakt, że Cron nie ma bladego pojęcia o Twojej zmiennej $PATH. Dobrym pomysłem jest stosowanie pełnych ścieżek do programów.

Korzystanie z polecenia crontab -e niesie ze sobą dodatkową korzyść w postaci sprawdzania trzeźwości naszego umysłu. Narzędzie to sprawdza, czy "kiedy" uruchomić zadanie, jest akceptowalne w przyzwoitych granicach zdrowego rozsądku, to znaczy czy może mieć sens. Przyjrzyjmy się przykładowi:

Użytkownik "rav" chciałby od poniedziałku do piątku, ale tylko w pierwszej połowie miesiąca, o 19:38 wykonać skrypt /usr/bin/somescript.sh. Może na swoim koncie wydać polecenie crontab -e, a następnie w swoim ulubionym edytorze (którym jest vim, bo taką sobie ustalił zmienną EDITOR), zapisze następującą linijkę:

Kod: Zaznacz cały

38 19    1-15 * 1-5        /usr/bin/somescript.sh
Crontab sprawdzi składnię pliku i jeśli wszystko jest poprawnie, nowa tablica zastąpi starą. Jeśli by się pomylił i wpisał:

Kod: Zaznacz cały

19 38    1-15 * 1-5        /usr/bin/somescript.sh
Crontab nakrzyczy na niego, że nie może wystąpić godzina 38:19!

Oczywiście Crontab dopuści możliwość utworzenia wpisu, które będzie się odwoływać do trzydziestego dnia lutego. Jest to poprawny wpis, choć intuicja podpowiada nam, że raczej będą problemy, z uruchomieniem zadania. Niemniej, z punktu widzenia składni wszystko jest w porządku. Widzimy tu, ze nie przed wszystkimi błędami Crontab nas ochroni.

Pojawia się jeszcze pytanie, gdzie fizycznie znajdują się te tablice? Czym są? Tablice znajdują się w pamięci maszyny, a fizycznie znajdują się na dysku w katalogu /var/spool/cron/crontab. W momencie ich modyfikacji, Cron wczytuje ich zawartość do pamięci. Sprawdzanie, czy nastąpiła modyfikacja, odbywa się co minutę. Rodzi się więc kolejne pytanie, czy nie prościej zwyczajnie wziąć, otworzyć i przeedytować tego paskudnika? Odpowiedź jest negatywna. Crontab sprawdzi nam tablicę pod kontem błędów formalnych. Dość łatwo jest pomylić się np. w kolejności pól. Zatem tam, gdzie jest to możliwe, zdecydowanie lepiej jest skorzystać z tego narzędzia.

Jeśli chcesz uruchamiać z konta roota, po wydaniu jako root polecenia crontab -e, w edytorze będziesz mógł edytować tablicę Crona. Jeśli chciałbyś uruchamiać skrypt z "tablicy systemowej", to masz takie katalogi, jak /etc/cron.*. W nich znajdują się skrypty, które są uruchamiane co godzinę, codziennie, co tydzień i raz w miesiącu. Wyjątkiem jest katalog /etc/crontab.d, który zawiera pliki z tablicami Crona. W formacie prawie takim samym, jak format tablicy użytkownika. Różnica polega na tym, że pojawia się dodatkowe pole pomiędzy "kiedy" a "co" uruchomić, które jest loginem użytkownika, z jakiego prawami ma zostać uruchomione polecenie.

Na samym początku wspomniałem o istnieniu drugiej tablicy, tablicy systemowej. Znajduje się w pliku /etc/crontab oraz w postaci plików w katalogu /etc/cron.d. Pliki te mają, jak mówiliśmy sobie na samym początku, nieco odmienną strukturę. Różnica jednak jest subtelna i poleca na dodaniu dodatkowego pola pomiędzy "kiedy", a "co". Pola, które można by nazwać umownie "jako kto". Określa ono z czyimi prawami zostanie wykonane polecenie. Wracając do naszego przykładu, miałby on wówczas postać:

Kod: Zaznacz cały

38 19    1-15 * 1-5       rav       /usr/bin/somescript.sh
Oczywiście powyższy artykuł nie wyczerpuje w całości tematu. Więcej informacji można uzyskać w podręcznikach systemowych, których poznanie gorąco rekomenduję: crontab(1), crontab(5), cron(8).

Dołożyłem wszelkich starań, by artykuł był pozbawiony błędów ortograficznych, interpunkcyjnych oraz rzeczowych. Gdyby jednak zdarzyło się, że gdzieś popełniłem błąd, proszę o informację w PW, bym mógł poprawić tekst. Jeśli coś nie jest zrozumiałe, lub brakuje jakiejś istotnej informacji, również proszę o kontakt.
Zablokowany