Rularea programata a aplicatiilor cu cron
Scris de Agkelos
Cron este un organizator de procese care ne usureaza mult munca. Ne ajuta sa rulam periodic programe la anumite ore din zi. Il putem utiliza in multe locuri, in general fiind folosit pentru intretinerea sistemului, backup sau actualizarea unor programe si baze de date.
crond este daemonul care ruleaza in fundal in sistemele UNIX si asemanatoare, si verifica in continuu lista de procese care trebuie rulate la o anumita data/ora. Principalul fisier de configurare este /etc/crontab in care sunt specificate programele care trebuie executate la o anumita ora, intr-o anumita data. De exemplu, daca deschideti /etc/crontab cu un editor de texte simplu veti gasi probabil mai multe linii printre care si cateva asemanatoare cu cele de mai jos:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
OK, ce inseamna asta ? Primele 4 randuri seteaza niste variabile care sunt folosite de crond la rulare. Variabilele respective (mai putin MAILTO) se gasesc in orice cont pe un sistem UNIX.
SHELL este interpretorul folosit de crond la rularea aplicatiilor.
PATH este variabila care pastreaza calea in care se poate gasi aplicatia care trebuie rulata. Daca se specifica app ca aplicatie, aceasta va fi cautata in toate directoarele din variabila PATH. Directoarele sunt specificate cu calea absoluta (incepand in /) si sunt separate de semnul ‘:’. Daca aplicatia nu este gasita in unul din directoarele specificate va trebui data calea absoluta a aplicatiei sau va trebui adaugat directorul aplicatiei in variabila PATH.
MAILTO trebuie sa contina un cont de pe sistemul local sau o adresa de mail. Dupa rulare unele scripturi pot afisa texte, mesaje de eroare sau confirmare a rularii. Aceste texte de iesire sunt trimise automat pe mail la contul specificat in MAILTO.
HOME este homedir al utilizatorului sub care ruleaza crond. In general nu e necesara variabila asta dar sunt unele programe care o cer, deci e bine sa aiba o valoare ( / ).
Bun, pana aici ne-am lamurit cu ce si cum dar sa vedem concret cum se foloseste. Daca va uitati in a doua parte a fisierului /etc/crontab vedeti o lista de chestii separate de spatii (sau TAB). De fapt sunt sapte campuri diferite, fiecare cu un scop bine determinat. Fiecare camp trebuie sa fie prezent.
Primele 5 campuri spun daemonului cand trebuie rulata o anumita aplicatie. Al saselea camp specifica userul care trebuie sa execute aplicatia respectiva. Al saptelea camp e comanda care trebuie executata.
Ne-am lamurit, acum sa vedem ce inseamna primul grup de 5 caractere de care ziceam ca ar fi data. Intr-adevar, e data si campurile sunt organizate dupa cum urmeaza:
- minutul - minutul din ora la care va fi rulata aplicatia;
- ora - ora din zi la care va fi rulata aplicatia;
- ziua (din luna) - in ce zi din luna va fi rulata aplicatia;
- luna - luna in care va fi rulata aplicatia;
- zi (din saptamana) - in ce zi din saptamana va fi rulata aplicatia.
Dupa cum vedeti, avem o flexibilitate destul de mare in specificarea perioadei in care va fi rulata aplicatia. Putem specifica fiecare termen din cei 5 sau putem pune un asterisc ( * ) pentru a specifica faptul ca aplicatia trebuie rulata la fiecare minut / zi / ora / luna in functie de campul in care il plasam. OK, hai sa facem ceva practic ca sa intelegeti functionarea. Luam exemplul de mai sus sa il studiem:
01 * * * * root run-parts /etc/cron.hourly
Ce e chestia de mai sus ? Primul element e 01 iar urmatorii 4 sunt marcati cu asterisc. Luandu-ne dupa ce am spus mai sus, asta inseamna ca aplicatia specificata ( run-parts /etc/cron.hourly ) va fi rulata in minutul 01 la fiecarei ore, in fiecare zi a lunii si a saptamanii, in fiecare luna. De ce ? Pentru ca singura conditie e sa fie minutul 01. Ciudat ? Mai vedem cateva exemple.
02 4 * * * root run-parts /etc/cron.daily
Alt exemplu, alta distractie. Vedem ca primul element e 02, al doilea 4 iar urmatoarele elemente care specifica data/ora sunt asteriscuri. Asta inseamna ca aplicatia ( run-parts /etc/cron.daily ) va fi rulata in minutul 02, la ora 4 in fiecare zi. Va fi rulata doar o data pe zi, pentru ca o singura data pe zi se indeplineste conditia (ora 4 - nu ora 16)
22 4 * * 0 root run-parts /etc/cron.weekly
Aici treburile devin putin mai interesante. Se specifica minutul (deci va fi rulat o singura data pe ora), se specifica ora (deci se va rula o singura data pe zi) si se specifica ziua saptamanii. Asta inseamna ca in perioada de 7 zile, scriptul va fi rulat o singura data. Ziua saptamanii e marcata cu 0. Ziua 0, e Duminica. Tot pentru Duminica se foloseste si 7 - stiu… sucks… :D
42 4 1 * * root run-parts /etc/cron.monthly
OK, avem si ultimul exemplu. Un script care e rulat la minutul 42, ora 4, in data de 1 a fiecarei luni. Daca s-a specificat ziua lunii, s-a pus o conditie in plus care e indeplinita doar o data pe luna. Deci, scriptul va fi rulat doar o data pe luna.
Bun, acum ca ne-am lamurit cum se specifica ora sa vedem si cum se poate programa o aplicatie sa fie rulata cand dorim noi. Am dat in zilele trecute un exemplu de cod care optimizeaza tabelele dintr-o baza de date. As vrea ca scriptul respectiv sa fie rulat zilnic la o ora la care nu se inregistreaza trafic mare (de ex 7.30). Pentru asta am facut scriptul si il apelez prin web (pentru ca serverul web sa il interpreteze si sa il ruleze). Pentru asta, de pe server ar trebui rulata o comanda de preluare a unui fisier prin web (wget, fetch, curl sau links) in fiecare zi la ora 7.30. Ca sa fac treaba functionala, adaug o linie in /etc/crontab care arata de forma:
30 7 * * * root links http://www.siteulmeu.ro/fisier.php
Astfel, in fiecare zi la ora 7.30 crond va rula links http://www.siteulmeu.ro/fisier.php, adica imi va executa scriptul. Nu e nevoie sa fie un script apelat prin web si nu e nevoie sa fie o comanda cu parametri. Poate fi la fel de simplu un script/program care e localizat pe server si care face ceva. De exemplu, daca avem aplicatia appname care vrem sa fie rulata zilnic, modificam linia de mai sus cu:
30 7 * * * root appname
Bun, ne-am lamurit si cu asta. Asta e tot ? Nu. Ca peste tot in UNIX, programatorii se gandesc la utilizator si incearca sa-i faca treaba cat mai usoara. Liniile care se gasesc ca default in crontab (cele din exemplu) nu sunt puse la intamplare. De fapt, run-parts este o aplicatie care este rulata pe aproape orice sistem UNIX. Ideea a fost implementata pentru prima oara in Debian. run-parts e un script shell care primeste ca parametru un director. La rulare, executa fiecare aplicatie/script din directorul specificat. Dupa cum se vede in liniile care sunt acolo ca default, aplicatia run-parts este apelata la fiecare ora cu directorul /etc/cron.hourly, o data pe zi cu directorul /etc/cron.daily, in fiecare zi a saptamanii cu directorul /etc/cron.weekly si o data pe luna cu directorul /etc/cron.monthly. Asta inseamna ca noi putem pune orice executabil in unul din directoarele astea si acesta va fi rulat in functie de directorul in care il punem. Daca punem un script in /etc/cron.hourly, acesta va fi rulat in fiecare ora. La fel si pentru celelalte directoare.
O idee buna, nu ? Putem face totul fara sa avem nevoie de sintaxa aia urata cu asteriscuri din /etc/crontab.
Am terminat ? Inca nu. Programatorii s-au gandit chiar mai mult la utilizator si la sistemele multi-user, asa ca crond a fost modificat pentru a putea fi utilizat de grupuri mari de utilizatori fara ca acestia sa se calce pe picioare. In sistemele multi-user fiecare utilizator are un fisier al lui in care se pastreaza cron-urile. Locatia depinde de sistemul de operare folosit, dar in majoritatea cazurilor e un subdirector din /var - de exemplu, /var/spool/cron/nume_utilizator in CentOS. Utilizarea se face dupa cum urmeaza:
In primul rand e necesar ca utilizatorul sa aiba un editor setat ca default. Se poate verifica daca exista prin utilizarea comenzii
echo $EDITOR
Daca nu e setat nici un editor, setati vi (sau oricare va place) ca editor folosind comanda
export EDITOR=vi
in bash. Pentru alte shell-uri cititi manualul si vedeti cum se exporta/seteaza o variabila de mediu.
OK, avem editorul. Acum trebuie sa editam fisierul pentru cron. Asta se face cu ajutorul comenzii crontab -e. Cand rulam comanda asta se deschide editorul setat si scriem data, ora si aplicatia exact ca in /etc/crontab. Apoi salvam si iesim iar editorul va salva tot ce am pus in fisierul cron al userului. Ca sa verificam daca e totul in regula, putem folosi crontabl -l:
root@mys [~]# crontab -l
10 1 1 * * root wget http://www.site-ulmeu.ro/
root@mys [~]#
Ca sa curatam lista de cronuri folosim crontabl -r.
OK, ne-am lamurit cum se seteaza cron-urile. Acum sa vedem ca admin cum le putem restrictiona. crond verifica in continuu fisierele /etc/cron.allow si /etc/cron.deny pentru a vedea daca userul sub care urmeaza sa fie rulata o aplicatie are dreptul sa ruleze. Daca vreti sa taiati accesul la cron utilizatorului xulescu, ii treceti numele in /etc/cron.deny in ideea in care politica e “toata lumea poate rula in afara de userii specificati”.
Se poate aplica o alta politica si anume “nimeni nu ruleaza cron in afara de userii specificati” caz in care in /etc/cron.deny se trece o singura linie si anume ALL. Asta inseamna ca nimeni nu are dreptul sa ruleze procese prin cron, exceptie facand userii care vor fi pusi in fisierul /etc/cron.allow.
Sper sa gasiti tutorialul util. Daca aveti intrebari astept sa le puneti pe forum.
Categoria: UNIX
