Dacă ai nevoie să programezi o sarcină unică pe un sistem Linux, `cron` s-ar putea să fie prea complex. În astfel de situații, familia de comenzi `at` este perfectă. Dacă vrei ca anumite procese să ruleze doar când sistemul tău are resurse disponibile, poți folosi `batch`.
Cum programezi sarcini în Linux
Daemonul `cron` gestionează o listă de activități ce rulează conform unui orar prestabilit. Aceste sarcini se execută în fundal la momentele specificate, oferind flexibilitate mare pentru sarcinile care trebuie repetate. Fie că ai nevoie să rulezi ceva o dată pe oră, zilnic la o anumită oră sau o dată pe lună/an, `cron` este soluția potrivită.
Însă, `cron` nu este ideal pentru sarcinile unice. Deși poți programa o sarcină unică cu `cron`, trebuie să îți amintești să ștergi înregistrarea din `crontab` după executarea sarcinii, ceea ce poate fi incomod.
În lumea Linux, când te confrunți cu o problemă, e foarte probabil ca altcineva să se fi luptat cu ea înaintea ta. Datorită longevității sistemelor de operare asemănătoare Unix, există o mare șansă să existe deja o soluție pentru problema ta.
Pentru problema sarcinilor unice, soluția există și se numește `at`.
Instalarea comenzii `at`
În cazul nostru, a fost necesară instalarea `at` pe Ubuntu 18.04 și Manjaro 18.1.0, deoarece pe Fedora 31 era deja instalat.
Pentru a instala pe Ubuntu, folosește această comandă:
sudo apt-get install at
După instalare, pornește daemonul `at` cu această comandă:
sudo systemctl enable --now atd.service
Pe Manjaro, instalează `at` cu această comandă:
sudo pacman -Sy at
După finalizarea instalării, pornește daemonul `at` cu:
sudo systemctl enable --now atd.service
Pe orice distribuție, poți verifica dacă daemonul `atd` rulează cu:
ps -e | grep atd
Cum utilizezi comanda `at` în mod interactiv
Pentru a folosi `at`, trebuie să îi specifici o dată și o oră de execuție. Există o mare flexibilitate în modul în care le poți scrie, pe care o vom discuta mai târziu.
Chiar și atunci când folosim interactiv, trebuie specificată data și ora. Dacă nu incluzi nimic în linia de comandă, sau introduci ceva ce nu e dată/oră, `at` va răspunde cu „Ora deturnată”, ca mai jos:
at
at banana
Datele și orele pot fi explicite sau relative. Să presupunem că vrei ca o comandă să fie executată peste un minut. `at` știe ce înseamnă „acum”, deci poți folosi `now` și adăuga un minut:
at now + 1 minute
`at` va afișa un mesaj și un prompt `at>`, așteptând comenzile pe care vrei să le programezi. Mai întâi, uită-te la mesaj:
`at` pornește o instanță a shell-ului `sh` și va rula comenzile în interiorul acestuia. Comenzile tale nu vor fi rulate în shell-ul Bash, care este compatibil cu `sh` dar are un set de caracteristici mai bogat.
Dacă scripturile tale folosesc funcții sau facilități oferite de Bash dar nu de `sh`, acestea vor eșua.
Poți testa ușor dacă scripturile tale vor rula în `sh`. Folosește comanda `sh` pentru a porni un shell `sh`:
sh
Linia de comandă va deveni un simbol dolar ($), și poți rula comenzile să verifici că funcționează corect.
Pentru a reveni la shell-ul Bash, tastează `exit`:
exit
Nu vei vedea ieșiri standard sau mesaje de eroare din comenzi. Asta pentru că shell-ul `sh` rulează ca o sarcină de fundal, fără interfață pe ecran.
Orice ieșire din comenzi – fie bună, fie rea – îți este trimisă pe email, prin sistemul intern de poștă, către cel care a folosit comanda `at`. Asta înseamnă că trebuie să configurezi un sistem de email intern.
Multe sisteme Linux nu au un sistem intern de email, deoarece rar este necesar. Cei care folosesc, folosesc sisteme ca `sendmail` sau `postfix`. Dacă sistemul tău nu are sistem email intern, poți cere scripturilor să scrie în fișiere sau să redirecționeze ieșirea în fișiere pentru a ține evidența.
Dacă o comandă nu generează ieșiri standard sau mesaje de eroare, nu vei primi email. Multe comenzi Linux indică succesul prin tăcere, deci în majoritatea cazurilor, nu vei primi un email.
Acum, e momentul să tastezi o comandă în `at`. Pentru acest exemplu, vom folosi un script mic numit `sweep.sh` care șterge fișierele *.bak, *.tmp și *.o. Tastează calea către comandă și apasă Enter:
Apare un alt prompt, și poți adăuga câte comenzi vrei. De obicei, e mai simplu să ai comenzile într-un script și doar să apelezi acel script din interiorul `at`.
Apasă Ctrl+D pentru a indica că ai terminat de adăugat comenzi. `at` afișează
După ce se execută sarcina, verifică poșta internă tastând:
Dacă nu ai email, consideră că a avut succes. Desigur, poți verifica și că fișierele *.bak , *.tmp și *.o au fost șterse.
Rulează din nou tastând:
at now + 1 minute
După un minut, verifică din nou email-ul tastând:
Avem email! Pentru a citi mesajul cu numărul unu, apasă 1 și Enter.
Am primit un email de la `at`, deoarece comenzile din script au generat mesaje de eroare. În acest exemplu, nu existau fișiere de șters, pentru că le-am șters când am rulat scriptul anterior.
Apasă D+Enter pentru a șterge email-ul, și Q+Enter pentru a ieși din programul de email.
Formate de dată și oră
Ai multă flexibilitate în formatul de timp pe care îl poți utiliza cu `at`. Câteva exemple:
Rulează la 11:00:
at 11:00 AM
Rulează mâine la 11:00:
at 11:00 AM tomorrow
Rulează la 11:00 în această zi, săptămâna viitoare:
at 11:00 AM next week
Rulează la această oră, în această zi, săptămâna viitoare:
at next week
Rulează la 11:00 vinerea viitoare:
at 11:00 AM next fri
Rulează la această oră vinerea viitoare:
at next fri
Rulează la 11:00, în această zi, luna viitoare:
at 11:00 AM next month
Rulează la 11:00 la o anumită dată:
at 11:00 AM 3/15/2020
Rulează peste 30 de minute:
at now + 30 minutes
Rulează peste două ore:
at now + 2 hours
Rulează la această oră mâine:
at tomorrow
Rulează la această oră, joi:
at thursday
Rulează la ora 12:00:
at midnight
Rulează la ora 12:00:
at noon
Dacă ești britanic, poți programa o comandă să ruleze la ora ceaiului (16:00):
at teatime
Vizualizarea cozii de sarcini
Poți folosi comanda `atq` pentru a vedea coada sarcinilor programate:
Pentru fiecare sarcină din coadă, `atq` afișează:
ID-ul sarcinii
Data programată
Ora programată
Cozile unde se află sarcina. Cozile sunt etichetate „a”, „b”, etc. Sarcinile programate cu `at` intră în coada „a”, iar cele programate cu `batch` (prezentată mai târziu) intră în coada „b”.
Persoana care a programat sarcina.
Folosirea `at` pe linia de comandă
Nu trebuie să folosești `at` interactiv; îl poți folosi și din linia de comandă, simplificând utilizarea sa în script-uri.
Poți introduce comenzi în `at` așa:
echo "sh ~/sweep.sh" | at 08:45 AM
Sarcina este acceptată și programată, iar numărul și data execuției sunt afișate ca înainte.
Folosirea `at` cu fișiere de comenzi
Poți stoca o serie de comenzi într-un fișier și să-l transmiți la `at`. Acesta poate fi un simplu fișier text cu comenzi, nu trebuie să fie un script executabil.
Folosește opțiunea `-f` (fișier) pentru a transmite numele fișierului:
at now + 5 minutes -f clean.txt
Poți obține același rezultat redirecționând fișierul la `at`:
at now + 5 minutes < clean.txt
Ștergerea sarcinilor programate din coadă
Pentru a șterge o sarcină programată din coadă, folosește comanda `atrm`. Dacă vrei să vezi coada mai întâi pentru a afla numărul sarcinii, poți folosi `atq`. Apoi folosește acel număr cu `atrm`:
atq
atrm 11
atq
Cum vizualizezi o prezentare detaliată a sarcinilor
După cum am menționat, poți programa sarcini în viitor, și uneori poți uita ce face o sarcină. Comanda `atq` afișează sarcinile din coadă, dar nu și ce fac ele. Pentru a vedea o vizualizare detaliată a unei sarcini, folosește opțiunea `-c` (cat).
Mai întâi, folosește `atq` pentru a găsi numărul sarcinii:
atq
Acum folosim sarcina cu numărul 13 și opțiunea `-c`:
at -c 13
Iată detalii despre informațiile obținute:
Prima linie: Comenzile vor rula sub shell-ul `sh`.
A doua linie: Comenzile vor rula cu un ID de utilizator și un ID de grup 1000. Acestea sunt valorile celui care a executat comanda `at`.
A treia linie: Persoana care primește email de la `at`.
A patra linie: Mască utilizator este 22. Aceasta este masca folosită pentru permisiunile implicite ale fișierelor create în această sesiune `sh`. Masca este scăzută din 666, rezultând 644 (echivalentul octal al lui rw-r–r–).
Restul liniilor: Majoritatea sunt variabile de mediu.
Rezultatele unui test. Un test verifică dacă directorul de execuție este accesibil. Dacă nu este, apare o eroare și execuția sarcinii este abandonată.
Comenzile de executat. Acestea sunt listate, la fel și conținutul scripturilor programate. Chiar dacă scriptul din exemplu a fost scris pentru a rula sub Bash, el va fi executat într-un shell `sh`.
Comanda `batch`
Comanda `batch` funcționează similar cu `at`, dar cu trei diferențe semnificative:
- Comanda `batch` poate fi folosită doar interactiv.
- În loc să programezi sarcini la un moment specific, le adaugi la o coadă, iar `batch` le execută când sarcina medie a sistemului este mai mică de 1.5.
- Datorită celui de mai sus, nu specifici data și ora cu comanda `batch`.
Când folosești `batch`, o apelezi simplu, fără parametri:
batch
Apoi, adaugă sarcinile exact ca și cu `at`.
Controlul accesului la comanda `at`
Fișierele `at.allow` și `at.deny` controlează cine poate folosi familia de comenzi `at`. Acestea se află în directorul `/etc`. În mod implicit, există doar fișierul `at.deny`, creat în timpul instalării.
Iată cum funcționează aceste fișiere:
- `at.deny`: Listează aplicațiile și entitățile care nu pot folosi `at`.
- `at.allow`: Listează cine poate folosi `at`. Dacă fișierul `at.allow` nu există, `at` folosește doar fișierul `at.deny`.
Implicit, oricine poate folosi `at`. Dacă vrei să restricționezi accesul, folosește fișierul `at.allow` pentru a lista pe cei care au voie. E mai simplu decât să adaugi toate persoanele care nu pot folosi `at` în fișierul `at.deny`.
Iată cum arată fișierul `at.deny`:
sudo less /etc/at.deny
Fișierul listează componente ale sistemului de operare care nu pot folosi `at`. Multe dintre ele sunt restricționate din motive de securitate, deci nu șterge nimic din fișier.
Acum, vom edita fișierul `at.allow`. Vom adăuga pe Dave și Mary, iar nimeni altcineva nu va avea voie să folosească `at`.
Introducem:
sudo gedit /etc/at.allow
În editor, adaugă numele, salvează fișierul:
Dacă altcineva încearcă să folosească `at`, va fi refuzat. De exemplu, dacă un utilizator numit Eric scrie:
at
va fi refuzat:
Eric nu este în fișierul `at.deny`. Odată ce ai introdus pe cineva în `at.allow`, tuturor celorlalți li se refuză accesul la `at`.
Excelent pentru Sarcini Unice
Atât `at` cât și `batch` sunt ideale pentru sarcinile pe care trebuie să le rulezi o singură dată. Recapitulare:
- Când trebuie să faci ceva ce nu este un proces obișnuit, programează-l cu `at`.
- Dacă vrei ca o sarcină să ruleze când încărcarea sistemului este scăzută, folosește `batch`.