====== 8. Înlănțuirea comenzilor, one linere ====== Comenzile în shell pot fi înlănțuite pentru a obține noi funcționalități. Anumite comenzi în shell pot primi diverse argumenter pentru a le altera funcționarea, în vreme ce altele primesc informații la standard input. Un one liner poate combina funcționalități precum folosirea operatorului ''|'' (//pipe//) sau expandarea comenzii (''%%$(...)%%'') pentru a crea rapid noi funcționalități în linia de comandă. ===== Subiecte abordate ===== * Operatorul ''|'' * Comanda ''for'' * One linere * Filtre de text * Expresii regulate ==== Utilitare folosite ==== * ''for'' * ''grep'', ''tr'', ''cut'' * ''basename'' ===== Exerciții ===== ==== Recapitulare ==== === Expandare comenzi (creare arhive) === Creați o arhivă ''.tar.gz'' cu toate fișierele din ''/usr/include'' mai mari de ''10KB''. Creați o arhivă ''.zip'' cu toate fișierele din ''/usr/include'' mai mari de ''10KB''. Creați o arhivă ''.zip'' cu toate fișierele din ''/usr/include'' mai mari de ''10KB'' accesate în ultimele 3 zile. Pentru accesare în ultimele 3 zile, folosiți opțiunea ''-atime'' a comenzii ''find''. === Informații despre dispozitive de tip caracter === Pentru dispozitivele de tip caracter din ''/dev'' afișați numele, majorul și minorul. Folosiți ''find'' cu opțiunea ''-type'' și parametrul corespunzător pentru a extrage dispozitivele de tip caracter. Folosiți ''stat'' cu opțiunile de formatare corespunzătoare și expandarea comenzii (''%%$(...)%%'') în conjuncție cu comanda ''find'' pentru afișarea numelui, majorului și minorului. **Bonus**: Sortați-le în funcție de major. Pentru sortare folosiți comanda ''sort''. Va trebui să specificați separatorul de câmpuri (folosind opțiunea ''-t'') și cheia de sortare (folosind opțiunea ''-k''). Pentru că avem cheie de sortare un număr va trebui să faceți sortare **numerică**. === Alte informații despre dispozitive de tip caracter === Câte dispozitive de tip caracter se găsesc în fiecare director din ierarhia ''/dev''? Folosiți ''find'' pentru a extrage dispozitivele de tip caracter. Folosiți ''dirname'' și expandarea comenzii (''%%$(...)%%'') în conjuncție cu comanda ''find'' de mai sus pentru a extrage doar numele directoarelor. Prelucrați output-ul de mai sus prin comanda ''sort'' pentru a-l sorta. Apoi folosiți output-ul astfel prelucrat prin comanda ''uniq'' cu opțiunea ''-c'' pentru a afișa numărul de apariții al fiecărui director. ==== Demo-uri ==== === Demo: Folosire filtre de bază === Folosire ''head'', ''tail'', ''sort'', ''uniq'', ''cut'', ''tr'', ''wc'' Generare parolă random Prelucrare date datornici === Demo: Expresii regulate === Exemple de expresii regulate Câte directive ''#include'' conțin fișierele din ''/usr/include''? Câte directive ''#include'' conțin fișierele de tip header C++ (''.hpp'')? === Demo: Folosire avansată grep și sort === Afișați fișierele din ierarhia ''/usr/include'' în ordinea numărului de apariții ale **cuvântului** ''FILE''. === Demo: Folosire ''for'' === for u in ana bogdan corina dan elena; do echo "user is $u"; done ==== Creare directoare în home-urile mai multor utilizatori ==== Pentru început adăugați în sistem utilizatorii ''ana'', ''bogdan'', ''corina'', ''dan'' și ''elena'' folosind utilitarul ''adduser'': sudo adduser ana sudo adduser bogdan ... Ca root, parcurgeți utilizatorii sistemului care au home-ul în ''/home/'', și creați un director ''public_html'' în home-ul fiecăruia. Ca să extragem utilizatorii al căror director home este în ''/home/'' folosim o construcție de forma grep '/home/' /etc/passwd Apoi filtrăm output-ul comenzii de mai sus cu ajutorul comenzii ''cut'' pentru a extrage doar prima coloană. Apoi folosiți ''for'' și expandarea comenzii în forma for user in $(grep ...); do ...; done Realizați apoi un one-liner sau un script care să șteargă directorul ''public_html''. Pentru a verifica prezența/absența directorului folosiți comanda ls -ld unde '''' este calea către directorul pe care dorim să-l verificăm. Pentru afișarea tuturor directoarelor ''public_html'' din home-urile utilizatorilor puteți folosi un glob în forma ls -ld /home/*/public_html/ ==== Creare directoare și schimbare permisiuni ==== Ca root, parcurgeți utilizatorii sistemului care au home-ul în ''/home/'', și creați un director ''public_html'' în home-ul fiecăruia. Schimbați ownership-ul acelui director la utilizator folosind ''chown''. Comanda ''chown'' este rulată doar de ''root'', adică folosiți ''sudo''. O formă de rulare a comenzii ''chown'' este sudo chown unde '''' este numele utilizatorului către care vrem să schimbăm ownership-ul iar '''' este calea către fișierul/directorul pentru care vrem să schimbăm ownership-ul. Pentru a verifica dacă a fost schimbat ownership-ul pe un director folosiți o construcție de forma ls -ld unde '''' este calea către directorul pentru care dorim să verificăm ownership-ul. Pentru afișarea de informații despre directoarele ''public_html'' din home-urile utilizatorilor puteți folosi un glob în forma ls -ld /home/*/public_html/ ==== Numele paginilor de manual dintr-o anumită secțiune ==== Afișați numele paginilor de manual din secțiunea 5. Numele sunt partea fără extensie din fișierele existente în directorul ''/usr/share/man/man5/''. De exemplu, pentru fișierul ''issue.5.gz'', numele este ''issue''. Recomandăm pașii de mai jos. Construiți glob-ul care să afișeze toate fișierele cu extensia ''.5.gz'' din directorul ''/usr/share/man/man5/''. **Nu** este nevoie să folosiți ''find'', puteți folosi un glob. Folosiți comanda ''basename'' pentru a extrage doar numele de bază al fișierului. Comanda ''basename'' ca argumente numele fișierulelor. Pentru a elimina extensia folosiți opțiunea ''-s'' a comenzii ''basename''. Opțiunea ''-s'' a comenzii ''basename'' primește ca argument extensia ce trebuie scoasă. Trebuie să scoateți extensia ''5.gz''. Din lista de mai sus, extrageți doar comenzile care încep cu o anumită literă. Adică din outputul de mai sus, folosiți o comandă de forma ''grep '^a''' pentru a extrage liniile care încep cu litera ''a'' folosind ''grep''. ==== Afișare informații despre fișiere ==== Dorim să afișăm informații despre fișiere folosind comanda ''stat'', comandă dedicată exact obținerii de informații despre fișiere. Afișați pentru fișierul ''/etc/passwd'' doar dimensiunea. **Indicație**: Folosiți comanda ''stat'' împreună cu opțiunea ''%%--format%%'' (sau ''-c'', forma scurtă a acestei opțiuni). Afișați pentru fișierul ''/etc/passwd'' inode-ul, dimensiunea și uid-ul, separate prin '','' (virgulă). Afișați numele, inode-ul, dimensiunea și uid-ul separate prin '','' (virgulă) pentru fișierele din ierarhia ''/etc/''. Afișați numele, inode-ul, dimensiunea și uid-ul separate prin '','' (virgulă) pentru fișierele din ierarhia ''/etc/'' care au extensia ''.conf''. Calculați totalul de octeți ocupat de fișierele din ierarhia ''/etc/'' care au extensia ''.conf''. Dacă aveți numere (câte unul pe linie) pe care vreți să le adunați, folosiți construcția filtrați output-ul prin comanda ''%%paste -s -d '+'%%''. Adică ceva de forma stat ... | paste -s -d '+' Output-ul comenzii de mai sus este acum o expresie aritmetică ce poate fi evaluată. Comanda ''%%paste -s -d '+'%%'' serializează liniile (opțiunea ''-s'') punând între ele caracterul ''+'' (pentru adunare). Pentru a efectua calculul, filtrați expresia aritmetică folosită mai sus prin comanda ''bc''. Comanda ''bc'' (un calculator în linia de comandă) primește o expresia aritmetică la standard input și o afișează la standard output. Adică o constructție de forma stat ... | paste -s -d '+' | bc ==== Fișiere ordonate după dimensiune ==== Listați primele 10 **fișiere obișnuite** (//regular files//) din ierarhia ''/etc'' (adică din toate directoarele, subdirectoarele și subdirectoarele acestora etc.) sortate în ordinea dimesiunii ocupate de fiecare fișier. Folosiți find pentru a extrage fișierele. Apoi folosiți expandarea comenzii și ''stat'' pentru a afișa doar numele și dimensiunea fișierului. Adică o construcție de forma stat -c ... $(find ...) Apoi filtrați output-ul comenzii de mai sus cu ajutorul comenzii ''sort'' pentru a sorta **numeric** în funcție de dimensiunea fișierului. Adică o construcție de forma: stat -c ... $(find ...) | sort ... Apoi filtrați output-ul prin comanda ''tail'' pentru a extrage doar primele ''10'' fișiere, în ordinea dimensiunii. Adică o construcție de forma: stat -c ... $(find ...) | sort ... | tail ==== Căutare cu grep ==== Folosiți ''grep'' pentru a selecta alias-urile cu destinația de forma ''nume.prenume@gmail.com'' din fișierul ''aliases'' din [[http://koala.cs.pub.ro/training/res/linux-admin/arc/cap-08-res.zip|arhiva capitolului]]. Intrările din fișierul ''aliases'' se consideră de forma ''alias: destinație''. ==== Generare parole aleatoare ==== Folosiți conținutul fișierului ''/dev/urandom'' pentru a genera o parolă aleatoare de 16 caractere. Folosiți comanda ''tr'' cu opțiunile ''-d'' și ''-c'' pentru a extrage doar caractere tipările (litere mici, litere mari, numere). Folosiți comanda ''head'' cu opțiunea ''-c'' pentru a extrage doar ''16'' caractere din output-ul anterior. Actualizați comanda de mai sus pentru a genera ''20'' de parola a câte ''16'' caractere. Recomandăm să **nu** folosiți ''for'' (merge, dar vrem să folosim ''fold'' :-P). Vedeți indicațiile legate de folosirea comenzii ''fold'' de mai jos. Comanda ''fold'' împarte informațiile primite la intrarea standard în linii pe care le afișează la ieșirea standard. Poate să extragă linii de dimensiune dată. Uzual se folosește în forma | fold unde '''' este o comandă care generează informații pe care apoi să le prelucreze comanda ''fold''. Extrageți ''20*16 = 320'' caractere aleatoare și apoi folosiți comanda ''fold'' cu opțiunea ''-w'' pentru a le grupa în seturi de câte ''16''. Adică o construcție de forma cat /dev/urandom | ... | fold -w 16