przystajnik

CRON – zapomniana usługa

Cron to jedna z niemal zapomnianych przez zwykłego użytkownika usług. Czasem wręcz nawet nie znana. Nic w tym dziwnego, bo każdy kto nie parał się obsługą serwerów, po przeczytaniu opisu jak wykonywać cyklicznie komendy/skrypty na Cron’ie, może mieć ciężki orzech do zgryzienia.

Jednak mamy nowy, lepszy, XXI wiek i wszystko da się zrobić prościej – nawet dogadanie się z Cron to nie jest już ekwilibrystyka konsolowa. Poznajcie zatem mój sposób na wykorzystanie Cron’a na zwykłym desktopie. Opis jest optymalny dla komputerów korzystających z Gnome/XFCE4 (lub ogólnie środowiska wykorzystującego GTK2).

Poznaj nowego-starego przyjaciela

Na początek nieco kurtuazji – oto Cron, cyt. „daemon zajmujący się okresowym wywoływaniem innych programów”. Innymi słowy, jest to usługa która tyka sobie w tle systemu operacyjnego, by w określonym przez użytkownika momencie, wykonać przypisane dla tego przedziału czasowego zadania/programy/skrypty. Ambitni mogą zapoznać się z zawartością pliku /etc/crontab i katalogów /etc/cron.*. Jednak nie czas na zabawy w konsoli.

Graficzna twarz Cron’a

By uniknąć zagmatwania się w opisy dotyczące poszczególnych plików konfiguracyjnych, oraz na przekór wszystkim złym prorok twierdzącym ‚bez pracy w konsoli do Linuksa nie podchodź’, zainstalujemy sobie pewien program. Program, który ujawni nam inne, bardziej medialne oblicze Cron’a. Programem tym jest gnome-schedule. W repozytoriach Debiana (Sid) znajdziemy wersję 2.1.1, w repozytoriach Ubuntu Jaunty – 2.0.2, Ubuntu Karmic i Ubuntu Lucid – 2.1.0. Wszystkie działają w ten sam sposób, drastycznych różnic pomiędzy wersjami nie ma. Program instalujemy, tak jak lubimy – albo za pomocą Synaptica albo apt-get install gnome-schedule. Gnome-schedule wymaga zainstalowanych: python-gtk2, python-support, python-gnome2, python-glade2 – to na wypadek, gdyby komuś zależności się buntowały.

Lista obowiązków

Jeżeli instalacja się powiodła, program znajdziemy w menu pod swojska brzmiącą nazwą Scheduled tasks. Niestety, nie jest on jeszcze do końca spolszczony, zatem trzeba wykazać minimum intuicji anglojęzycznej przy przełączaniu opcji.

gs1

Główne okno prezentuje nam listę obowiązków naszego przyjaciela Cron’a. Działania te dzielą się na wykonywane co jakiś czas (Recurrent), oraz jednorazowe (Once). Pierwsza ikonka z lewej (‚Nowy’) pozwala skonfigurować nam takie zadanie i dodać je do listy. Kolejne ikony to ‚Edycja’ wybranego zadania, ‚Usuń’ – to chyba oczywiste, oraz ‚Run Task’ – by przetestować dodaną czynność (nie zawsze działa?). ‚Templates’ i ‚Advanced’ umożliwiają, odpowiednio, zarządzenie schematami zadań (tworzone zadania można dopisywać do tej listy, bo potem nie tworzyć ich ponownie) oraz przełączanie widoku listy wg. nomenklatury Cron’a.

Pragnąłbym, aby…

Po wduszeniu ikony ‚Nowy’ i wyborze typu zadania, ukazuje się nam zgrabne okienko, w którym będziemy mogli poprosić Cron’a o zrobienie różnych rzeczy.

gs2

Zaczynając od końca – zagłębiamy się w specyfikę cyklicznego wykonywania poleceń. Do wyboru mamy dwa tryby konfiguracji okresu występowania zdarzenia:

‚Basic’ – określamy, by Cron uruchomił nasze polecenie o każdej pełnej minucie, bądź godzinie, dniu, miesiącu, tygodnia, itp.

‚Advanced’ – aby wymknąć się ramom ‚pełnej godziny/minuty/itp’, w tym trybie mamy możliwość dokładnego ustalenia, o której minucie/godzinie/dniu miesiąca/miesiącu roku/dnia tygodnia ma się coś wykonać

Po ustaleniu terminu, w górnej części okna nadajemy nazwę zadaniu (‚Description’ – by ładnie prezentowało się na liście), oraz najważniejsza część ‚Command’ – co też Cron powinien uruchomić. Tu napotykamy pierwszy zgrzyt, bo jeśli ktoś oczekiwał, że będzie stawiał ptaszki przy liście programów, które się mają wykonać – tak nie będzie. Dlaczego? Taka jest specyfika Linuksa i już. Dzięki temu, mamy pełną kontrolę i swobodę, co ma się wykonywać. Niestety, trzeba będzie znać nazwy programów/poleceń.

Mów do mnie jeszcze, czyli teorii łyk

Linijka ‚Command’ jest na tyle istotna, że wymaga dokładniejszego omówienia. Chcemy, aby np. o godzinie 13.00 uruchamiał się nam klient poczty. Wpisujemy zatem nazwę programu, np. thunderbird. I co? I nic się nie uruchomi. Frustracja.

Potrzebne jest zrozumienie pewnych zasad, którymi rządzi się Cron. Wszystko co mu każemy uruchomić, uruchamia on z prawami użytkownika (naszymi), jednak we własnym środowisku które domyślnie nie posiada żadnych zmiennych. Dlatego wszystko musimy mu podać jak na tacy, jeśli chcemy, żeby działanie odniosło skutek dla naszego pulpitu. To oczywiście sytuacja skrajna, bo gdy będziemy wykonywali komendy, które nie czują konieczności wizualizacji swojego działania na ekranie użytkownika, to ten problem odpada.

Ta specyfika braku wartości w zmiennych, skutkuje też tym, że wpisując nazwę programu musimy podać pełną ścieżkę do niego (jedna ze zmiennych to PATH, która przechowuje domyślne ścieżki, które system ma przeszukiwać, jeśli wpisujemy jakieś polecenie. Dlatego piszemy ‚ls’, a nie ‚/bin/ls’). Czyli nie ‚thunderbird’, ale ‚/usr/bin/thunderbird’. Dociekliwi zauważą, że możliwe są proste sposoby, aby jednak skrypt uruchamiany przez Cron’a posiadał zmienne ze środowiska użytkownika – ale póki co, rozważamy podstawy.

Wiemy już, że polecenia w linii ‚Command’ musimy wpisywać wraz ze ścieżką (/bin/ls, /usr/bin/thunderbird, /usr/bin/xclock). Skąd dowiemy się, gdzie ukrywa się jakiś program? Najszybciej wpisując w konsoli ‚whereis nazwa_programu’ – otrzymamy ścieżkę/ścieżki prowadzące do tej nazwy.

Wiemy też, że program uruchomione w środowisku Cron’a nie wyświetli się nam na pulpicie. Znowu za pomocą magicznej zmiennej, pokażemy mu gdzie jest ekran X’ów. Przed każdym poleceniem wpiszemy DISPLAY=:0.0, bo w większości przypadków nieawaryjnych, właśnie taki numer ma ‚ekran’ graficzny naszego serwera X.

Tyle wywodów, a dla tych którzy znoszą cierpliwie tę pisaninę by dowiedzieć się, co po prostu wpisać, żeby zadziałało:

DISPLAY=:0.0 /usr/bin/thunderbird

No po co mi to wszystko

Można powiedzieć, sukces. Mamy listę zadań, dopisujemy sobie swoje własne polecenia, które uruchomią się o takim, a nie innym czasie. Czegoś brakuje? Ciągle funkcjonalności. Po pierwsze, co nam po Thunderbirdzie startującym o godzinie, jeśli ikonkę do uruchomienia mamy w zasięgu myszki. Po drugie, czy ten Cron potrafi się z nami komunikować w jakiś sposób, tak, byśmy wiedzieli co się dzieje, bez zerkania do logów systemowych?

Odpowiadając na pytanie drugie – tak, potrafi. Wszyscy znają i lubią piękne ‚dymki’ wyświetlające różne informacje. Zróbmy tak, aby wyświetlały nam, co się dzieje w Cronie!

Do tego celu potrzebujemy paczki libnotify-bin. Po instalacji (jak zawsze), dostaniemy do rąk program pt. ‚notify-send’. Co mu podamy jako parametr, to on nam to pięknie wyświetli w dymku. Rozwijamy zatem naszą linijkę poleceń dla Cron’a.

DISPLAY=:0.0 /usr/bin/notify-send "Cron" "Uruchamiam klienta poczty. Sprawdź wiadomości." -i notification-message-email && DISPLAY=:0.0 /usr/bin/thunerbird

Powyższym zestawień poleceń rozwiązujemy dwie kwestie, a nawet trzy. Pierwsza, to dzięki zmiennej DISPLAY przed każdym poleceniem, wynik jego działania będzie wiedział, gdzie się wyświetlić. Po drugie, notify-send poinformuje nas, co Cron zamierza – można z tego stworzyć niejako standard przy konstruowaniu zadań dla Cron’a. Po trzecie, dzięki ‚&&‚ między poleceniami, możemy wykonać ich w jednej linii, ile chcemy.

Nabrało to wszystko lekkich rumieńców, czyż nie?

Praktyka

Do czego to wszystko może się przydać? No cóż…

Tworzenie backup’ów. Zechcemy zabezpieczyć przed przypadkowym zepsuciem np. katalog .config? Proszę bardzo:

DISPLAY=:0.0 /usr/bin/notify-send "Cron" "Tworzenie kopii zapasowej katalogu .config do ~/_backup" -i notification-message-email && /usr/bin/mkdir /home/nazwa_uzytkownika/_backup && /usr/bin/tar cfz /home/nazwa_uzytkownika/_backup/config.tgz /home/nazwa_uzytkownika/.config

Chcemy przeskanować programem antywirusowym katalog, do którego ściągamy pliki z internetu? (Aby nie rozdawać zarażonych znajomym):

DISPLAY=:0.0 /usr/bin/notify-send "Cron" "Sprawdzam antywirusem katalog 'Pobrane'" -i notification-message-email && DISPLAY=:0.0 /usr/bin/clamtk /home/nazwa_uzytkownika/Pobrane

Czyszczenie katalogu domowego z plików *.*~ (tymczasowe backupy edytowanych plików – uwaga, upewnij się, że na pewno tego chcesz!):

DISPLAY=:0.0 /usr/bin/notify-send "Cron" "Czyszczę katalog domowy z plików *.*~" -i notification-message-email && /usr/bin/find ./ -name *.*~ -print0 | /usr/bin/xargs -0 /bin/rm

Co jakiś czas Cron użyje zasugeruje, żebyś po prostu rozprostować kości.

DISPLAY=:0.0 /usr/bin/notify-send "Cron" "Podejdź do okna i sprawdź, czy na zewnątrz istnieje jeszcze ludzka cywilizacja w takiej formie jak pamiętasz" -i notification-message-email

Niby nic, a cieszy

To już koniec opowieści. Dotarliśmy do wielkiego finału.

Jak widać, Cron może się przydać i na zwykłym komputerze biurkowym. Uproszczenie jego obsługi (Crona) za pomocą programu gnome-schedule to niewątpliwy krok naprzód, nadal straszą nieco ciągi poleceń, które wpisujemy jako zadania do uruchomienia. Ale to taki urok systemu. Cron nie jest też przymusem – można się bez niego obyć, jeżeli powyższe zestawy poleceń wywołują u Ciebie ból zębów.

Temat nie został oczywiście wyczerpany. Gnome-schedule posiada jeszcze ukryty hidden-screen, do którego dostaniemy się po uruchomieniu go przez ‚gksu gnome-schedule’. Pojawi się wtedy opcja tworzenia zadań wykonywanych z uprawnieniami root’a, oraz dostęp do zadań wszystkich użytkowników.

Szczególnie interesujące i pociągające jest wykonywanie zadań z prawami root’a. Co pierwsze przychodzi na myśl? Np. czyszczenie dysku z zalegających paczek w /var/cache/apt/archives.

Ale to już inna opowieść.
 

Post navigation

  • Bardzo przydatny wpis, ogólnie nt. cron’a można doszukać się wielu informacji w przeróżnych źródłach, ale ten wpis porzadkuje wszystko bardzo ładnie i przedstawia w miły sposób.
    Świetnie się czyta, gratuluję obszernego i bardzo ciekawego wpisu.

  • Ciekawy program. Warto dodać, że dla systemów innych niż Debian, *buntu wymagane jest uruchomianie przy starcie daemona at (na Archu ‚atd’).

  • Pingback: Czytelny jak Corntab | przystajnik()

Translate »