Differences

This shows you the differences between two versions of the page.

Link to this comparison view

uso:laboratoare:laborator-06 [2016/11/15 22:32]
cstaniloiu Add lab06
uso:laboratoare:laborator-06 [2022/11/10 15:44] (current)
iustina.caramida
Line 1: Line 1:
 +====== Laborator 06 - Îmbunătățirea lucrului în linia de comandă ======
  
-====== Laborator 06 - Interfața în linia de comandă ​ ​======+Principalul atu al utilizării aplicațiilor în linie de comandă, și nu în mediul grafic, este viteza cu care rezolvăm anumite sarcini. Această viteză este dată de posibilitatea de combina utilitare ​în linia de comandă ​pentru a automatiza procese manuale, repetitive. Întotdeauna ne dorim să fim mai rapizi și să automatizăm cât mai mult din sarcinile noastre, deoarece cu cât ne terminăm treaba mai repede, cu atât avem mai mult timp liber la dispoziție.
  
-===== Suport laborator ======+De regulă, cu cât petrecem mai mult timp cu mâna pe tastatură și mai puțin pe mouse, cu atât suntem mai rapizi. Aliniate la această idee, aplicațiile ne pun la dispoziție scurtături pe care suntem încurajați să le folosim pentru a ne utiliza timpul mai eficient.
  
-  * [[:​uso:​cursuri:​curs-06|Cursul 06]] 
-  * [[http://​books.google.com/​books?​id=_JFGzyRxQGcC&​pg=PA365|Capitolul 12 - Shell scripting]] ​ 
-      * Secțiunile 12.1, 12.2, 12.6, 12.7  
-      * Celor interesați să afle și mai multe le recomandăm [[http://​www.tldp.org/​LDP/​Bash-Beginners-Guide/​html/​|TLDP - Bash guide for beginners]] și [[http://​www.cyberciti.biz/​open-source/​learning-bash-scripting-for-beginners/​|articolele sugerate aici]] 
-  * [[:​uso:​resurse:​cheatsheet|Cheatsheet]] - în special pagina a doua 
-  * [[http://​xkcd.com/​1205/​|Is it worth spending time to automate a task?]] 
-  * Motto laborator: //Never use the graphical tool; always learn the old Unix tool. You'll be far more effective over time and your data will still work in 2030.// 
-===== Demo ====== 
  
-==== Redirectare =====+{{page>​uso:​laboratoare:​laborator-06:​inspect-fs&​nofooter&​noeditbutoon}} 
 +{{page>​uso:​laboratoare:​laborator-06:​inspect-files&​nofooter&​noeditbutoon}} 
 +{{page>​uso:​laboratoare:​laborator-06:​inspect-shell&​nofooter&​noeditbutoon}} 
 +{{page>​uso:​laboratoare:​laborator-06:​improve-terminal&​nofooter&​noeditbutoon}} 
 +{{page>​uso:​laboratoare:​laborator-06:​improve-cli-summary&​nofooter&​noeditbutoon}}
  
-Redirectare ''​stdout''​ (standard output, în general mesaje afișate prin comenzi similare cu ''​printf''​ din C). De exemplu, într-un sistem în care avem multe procese, e greu sa urmărim direct în consolă output-ul comenzii ''​ps'':​ 
- 
-<code bash> 
-student@midgard:​~$ ps -f -u student > stdout.txt ​ 
-student@midgard:​~$ cat stdout.txt 
-</​code>​ 
- 
-Putem redirecta **doar** mesajele de eroare către un fișier. Scenariu: Vrem să găsim toate fișierele cu extensia ''​*.conf''​ din directorul ''/​etc''​. ​ 
- 
-<code bash> 
-student@midgard:​~$ find /etc -name '​*.conf'​ 
-(...) 
-find: `/​etc/​ppp/​peers':​ Permission denied 
-(...) 
-</​code>​ 
- 
-Ne deranjează mesajele de eroare din cauza lipsei drepturilor de citire asupra unor fișiere sau directoare. Pentru aceasta vom folosi: 
- 
-<code bash> 
-student@midgard:​~$ find /etc -name '​*.conf'​ 2> errors.txt 
-student@midgard:​~$ cat errors.txt 
-</​code> ​ 
- 
-Putem face combinații acum: redirectăm erorile într-un fișier și rezultatele în alt fișier: ​ 
- 
-<code bash> 
-student@midgard:​~$ find /etc -name '​*.conf'​ 2> errors.txt > stdout.txt 
-</​code>​ 
- 
-<​hidden>​ 
-Nu neapărat cu redirectări,​ dar aș vrea să le dați mai multe use-case-uri cu find, de exemplu: pot căuta după anumite fișiere și să execute o comandă asupra lor: ''​rm'':​ 
- 
-<code bash> 
-find . -name '​*.tmp'​ -exec rm -f {} \; 
-</​code>​ 
- 
-Mai mult cu titlul //for their info//​. ​ 
-</​hidden>​ 
- 
-În cazul în care dorim să redirecționăm **toate** mesajele afișate de o comandă, la grămadă, folosim operatorul ''&>'':​ 
- 
-<code bash> 
-student@midgard:​~$ find /etc -name '​*.conf'​ &> find_output.txt 
-</​code> ​ 
- 
-<note tip> 
-Reamintiți-vă de la procese ''​procfs'',​ montat în ''/​proc''​. Pentru fiecare proces identificat printr-un PID, aveam directorul ''/​proc/​19827/​fd'',​ care conținea link-uri simbolice către fișierele deschise de acel proces. Pentru fiecare proces în acel director găseam ''​0,​ 1, 2''​. Acestea reprezintă respectiv: 
- 
-  * ''​0''​ - intrarea standard (stdin). Exemplu: tastatura 
-  * ''​1''​ - ieșirea standard (stdout). Exemplu: mesaje afișate cu ''​printf''​ de un program C 
-  * ''​2''​ - ieșirea standard de eroare (stderr), unde se duc mesaje precum cele afișate de find mai sus. 
-</​note>​ 
- 
-Putem redirecta outputul și către device-uri virtuale, cum ar fi ''/​dev/​null''​. În general facem acest lucru deoarece vrem să executăm o anumită comandă (într-un program sau într-un script), fără a ne interesa outputul ei. Pentru exemplul cu ''​find''​ de mai sus, să zicem că dorim să ignorăm erorile: 
- 
-<code bash> 
-student@midgard:​~$ find /etc -name '​*.conf'​ 2> /​dev/​null ​ 
-</​code>​ 
- 
-==== Înlănțuirea comenzilor ===== 
- 
-Este o metodă foarte bună prin care executăm mai multe comenzi simultan, în funcție, eventual, de anumite condiții. ​ 
- 
-  - **Înlănțuire simplă: '';''​**:​ execută comenzile una după alta, indiferent de rezultatul comenzii anterioare: <code bash> root@asgard:​~#​ apt-get update ; apt-get upgrade ; apt-get dist-upgrade </​code>​ În exemplul de mai sus am executat un update complet (de surse de unde sunt luate pachetele și de pachete) al unui sistem Ubuntu. ​ 
-  - Dacă vrem să înlănțuim două comenzi, dar s-o executăm pe a doua **doar** dacă prima s-a terminat cu succes, vom folosi operatorul ''&&'':​ <code bash> student@midgard:​~$ grep www-data /etc/passwd > /dev/null && echo "Avem userul www-data"​ </​code>​ 
-  - Dacă vrem să înlănțuim două comenzi, dar s-o executăm pe a doua **doar** dacă prima s-a terminat cu eșec, vom folosi operatorul ''​||'': ​ <code bash> student@midgard:​~$ grep costel /etc/passwd > /dev/null || echo "Nu avem userul costel"​ </​code>​ 
- 
-<note tip>În general, pentru a vedea ce rezultat a avut o comandă, inspectăm variabila ''​$?'':​ 
- 
-<code bash> 
-student@midgard:​~$ ls -l ~ > out.txt 
-student@midgard:​~$ echo $? 
-0 
-student@midgard:​~$ cat /​etc/​sudoers 
-student@midgard:​~$ echo $? 
-1 
-</​code>​ 
- 
-Observăm că o comandă care s-a încheiat cu success returnează ''​**0**''​. ​ 
-</​note>​ 
- 
-<note important>​Atenție! Toți operatorii de redirectare din acest demo ''​2>'',​ ''&>'',​ ''>''​ trunchiază conținutul fișierului,​ dacă acesta exista. Ca alternativă aveam //append mode//, care se poate aplica și aici, fără probleme, astfel: 
-''​%%2>>​%%'',​ ''​%%&>>​%%'',​ ''​%%>>​%%''​. 
-</​note>​ 
- 
-==== Comunicarea interprocese,​ folosind pipe ===== 
- 
-<​hidden>​ 
-Insistați puțin pe faptul că un proces transmite stdout-ul lui celuilalt proces ca stdin. E foarte important! 
-</​hidden>​ 
- 
-Care e diferența dintre cele două comenzi de mai jos? Câte procese se execută pentru fiecare dintre cele două comenzi? 
- 
-<code bash> 
-student@midgard:​~$ cat /etc/passwd | cut -d':'​ -f1 
-student@midgard:​~$ cut -d':'​ -f1 < /etc/passwd 
-</​code>​ 
- 
-Dorim să inspectăm jurnalul (log-ul) pachetelor instalate sau șterse în sistemul nostru Ubuntu. Dar ne interesează doar ultimele 40 de acțiuni. Pentru a putea obține și un output în care putem căuta și filtra text ca în pagina de manual vom folosi ''​less'':​ 
- 
-<​hidden>​ 
-Faceți demo și arătați cum ''​less''​ funcționează ca ''​man ls''​ de exemplu. ​ 
-</​hidden>​ 
- 
-<code bash> 
-student@midgard:​~$ tail -n 40 /​var/​log/​bootstrap.log | less 
-</​code>​ 
- 
-<note tip> 
-Dacă vrem să monitorizăm fișierel de tip log în timp real, folosim comanda 
-<code bash> 
-tail -f /​path/​to/​logfile ​ 
-</​code>​ 
-unde ''/​path/​to/​logfile''​ este calea către fișierul pe care vrem să-l monitorizăm în timp real. 
-</​note>​ 
- 
-Similar putem cere primele 40 de acțiuni jurnalizate în acest fișier: ​ 
- 
-<code bash> 
-student@midgard:​~$ head -n 40 /​var/​log/​bootstrap.log | less 
-</​code>​ 
- 
-Scenariu: suntem administratorii unui server. Dorim să folosim un one liner pentru a afișa ultimii 30 de utilizatori (doar username-ul lor, plus trebuie evitate duplicatele,​ ne interesează 30 de persoane) care s-au autentificat în sistemul nostru, să îi sortăm alfabetic: 
- 
-<code bash> 
-root@testingsrv:​~$ last -30 | cut -d ' ' -f1 | sort | uniq 
-</​code>​ 
- 
-Totuși există o problemă cu comanda de mai sus: ''​last''​ afișează pe ultima linie un mesaj de forma  
-<code bash> 
- 
-wtmp begins Mon Nov  3 19:24:55 2014 
-</​code>​ 
- 
-Ne deranjează ultimele două linii (un spațiu gol și mesajul descris mai sus) și deci vrem să le eliminăm: 
- 
-<code bash> 
-root@testingsrv:​~$ last -30 | head -n -2 | cut -d ' ' -f1 | sort | uniq 
-</​code>​ 
- 
-==== Variabile în terminalul Bash ===== 
- 
-<code bash> 
-student@midgard:​~$ MY_VAR="​value"​ 
-student@midgard:​~$ a=1 
-student@midgard:​~$ echo $a 
-student@midgard:​~$ echo $MY_VAR 
-</​code>​ 
- 
-Într-o variabilă putem salva și output-ul unei comenzi pentru a îl transmite ca parametru altei comenzi (similar cu un pipe). Spre exemplu, dorim să ștergem toate fișierele cu extensia ''​*.tmp''​ din directorul curent: 
- 
-<code bash> 
-student@midgard:​~$ rm -f $(find . -name '​*.tmp'​) 
-</​code>​ 
- 
-==== Variabile speciale în terminalul Bash ===== 
- 
- 
-^ Variabila ​    ^ Semnificație ​                                ^ 
-| **''​$$''​** ​   | PID-ul procesului curent ​                    | 
-| **''​$!''​** ​   | PID-ul ultimului proces lansat in background | 
-| **''​$?''​** ​   | Valoarea de exit a ultimei comenzi ​          | 
-| **''​$_''​** ​   | Ultimul argument al ultimei comenzi (similar cu ''​ALT+.'' ​  | 
- 
-Putem folosi comanda ''​echo''​ și să îi transmitem parametru variabilele respective, pentru a vedea rezultatul lor.  
-==== Variabile de mediu ===== 
- 
-Variabilele de mediu sunt un set de variabile care afectează modul în care un program rulează. În general, un proces moștenește variabilele de mediu ale procesului părinte. Astfel, pentru procesul asociat rulării unei comenzi, sunt moștenite variabilele shell-ului. 
- 
-Pentru a vedea variabliele de mediu definite, putem folosi comanda ''​env''​ fără nici un parametru. 
- 
-<​code>​ 
-student@uso:​~$ env 
-</​code>​ 
- 
-Pentru a defini o variabilă de mediu folosim: 
-<​code>​ 
-student@uso:​~$ export VARIABLE=value 
-</​code>​ 
- 
-<​note>​ 
-Dacă nu folosim ''​export''​ variablia nu va fi moștenită de procesele copii. 
-</​note>​ 
- 
-Variabliele de mediu se scriu în mod obișnuit cu litere mari. Exemple de variabile de mediu: 
-  * ''​PATH''​ - o listă de directoare folosite de shell pentru a găsi executabilul asociat comenzii. Directoarele sunt separate prin '':''​. 
-  * ''​HOME''​ - directorul ''​home''​ al utilizatorului curent. 
-  * ''​USER''​ - utilizatorul curent 
-  * ''​OLDPWD''​ - calea directorului anterior 
-  * ''​EDITOR''​ - editorul implicit. 
- 
-==== Globbing ==== 
- 
-  - Dorim să afișăm toate fișierele cu extensia ''​.conf''​ din ''/​etc'',​ care încep cu ''​a,​ b, c, d''​ sau ''​e'':​ <code bash> student@midgard:​~$ ls -l /​etc/​[a-e]*.conf</​code>​ 
-  - Dorim să afișăm fișierele (sau directoarele) cu extensiile ''​.conf''​ sau ''​.d''​ din ''/​etc'':​ <code bash> student@midgard:​~$ ls -ld /​etc/​*{.conf,​.d}</​code>​ De ce am folosit parametrul ''​-d''​ la ''​ls''?​ 
-  - Dorim să afișăm fișierele (sau directoarele) cu extensiile ''​.conf''​ sau ''​.d''​ din ''/​etc''​ care nu încep cu ''​a,​ b, c'':​ <code bash> student@midgard:​~$ ls -ld /​etc/​[^abc]*{.conf,​.d}</​code>​ 
- 
- 
-==== Shell scripting ==== 
- 
-În loc să scriem one-linere putem automatiza execuția mai multor într-un fișier, numit script, care va fi interpretat de Bash linie cu linie. În general shell script-urile sunt fișiere care au extensia ''​.sh''​ și pe prima linie au așa-numitul **shebang**,​ o linie care începe cu ''​**#​!**''​ prin care instruim terminalul ce interpretor sa folosească. Iată un exemplu simplu: 
- 
-<code bash hello.sh>​ 
-#!/bin/bash 
- 
-echo "​Hello,​ World!"​ 
-</​code>​ 
- 
-Preuspunând că fișierul ''​hello.sh''​ e salvat în ''/​home/​student''​ acesta se execută ca un binar generat în urma compilării unui program C. Este foarte important de observat că trebuie să avem drepturi de execuție asupra lui: 
- 
-<code bash> 
-student@midgard:​~$ cd ~; ls -l hello.sh 
--rw-rw-r-- 1 student student 34 nov  8 21:44 hello.sh 
-student@midgard:​~$ ./hello.sh 
-bash: ./hello.sh: Permission denied 
- 
-student@midgard:​~$ chmod +x hello.sh; ls -l hello.sh 
--rwxrwxr-x 1 student student 34 nov  8 21:44 hello.sh 
-student@midgard:​~$ ./hello.sh 
-Hello, World! 
-</​code>​ 
- 
-Înlănțuirea de comenzi de upgrade poate fi transpusă într-un script, astfel: 
- 
-<code bash upgrade_ubuntu.sh>​ 
-#!/bin/bash 
- 
-# This is a comment 
-echo "​Upgrading Ubuntu!"​ 
- 
-# Please run this script as root 
-apt-get update 
-apt-get upgrade 
-apt-get dist-upgrade 
- 
-# Make some cleanup 
-echo "​Cleaning dependencies not needed anymore"​ 
-apt-get autoremove 
- 
-echo "​Cleaning retrieved package files" 
-apt-get autoclean 
-</​code>​ 
- 
-<note tip>La **shebang** în loc să specificăm calea absolută către interpretor,​ am putea interoga variabila de mediu, pentru a avea scriptul //​portabil//​ (e posibil ca pe alte stații interpretorul Bash să nu fie localizat în ''/​bin/​bash''​. Să urmărim prima linie din exemplul de mai jos: 
- 
-<code bash hello.sh>​ 
-#​!/​usr/​bin/​env bash 
- 
-echo "​Hello,​ World!"​ 
-</​code>​ 
- 
-</​note>​ 
- 
-===== Exerciții ===== 
- 
-<note important>​ 
-Pe parcursul exercițiilor,​ rulați părțile din exerciții pas cu pas. Scrieți o comandă, verificați că funcționează. Adăugați apoi o prelucrare cu operatorul ''​|''​ (//pipe//) și verificați că funcționează. Și tot așa, **din aproape în aproape**. 
-</​note>​ 
- 
-==== [1] Cine pe cine include (2p) ==== 
- 
-Dorim să afișăm fișierele din ierarhia ''/​usr/​include''​ care includ header-ul ''​features.h'',​ împreună cu linia unde acest antet apare. Vom folosi comanda ''​grep''​ și opțiunile acesteia și vom construi un one liner. 
- 
-Pentru început, folosiți ''​grep''​ pentru a căuta recursiv în ierarhia ''/​usr/​include''​ fișierele care conțin șirul ''​features.h''​. Opțiunea ''​-r''​ (de la //​recursive//​) este cea care permite căutarea recursivă într-o ierarhie. 
- 
-Completați opțiunile comenzii ''​grep''​ de mai sus cu opțiunea care permitea afișarea numărului liniei din cadrul fiecărui fișier unde a fost găsit match-ul. Pentru a afla opțiunea ''​grep''​ care afișează numărul liniei pe care a fost găsit șirul, căutați în pagina de manual a comenzii ''​grep''​ șirul ''​line-number''​. 
- 
-În output-ul obținut mai sus sunt afișate trei elemente separate de caracterul două puncte ('':'',​ //colon//): numele fișierului,​ numărul liniei pe care a fost făcut match și conținutul liniei. Afisați doar numele fișierului și numărul liniei pe care a fost făcut match. 
- 
-<note tip> 
-Folosiți comanda ''​cut''​ și extrageți doar coloanele de interes: coloana 1 și coloana 2. 
-</​note>​ 
- 
-<​solution>​ 
-<code bash> 
-grep -Rn features.h /​usr/​include/​ | grep \#include | cut -d':'​ -f1,2 
-</​code>​ 
-</​solution>​ 
- 
-==== [2] Mesaj de întâmpinare (2p) ==== 
- 
-Dorim să afișăm un mesaj de întâmpinare custom pentru momentul în care un utilizator deschide un shell. Mesajul vrem să fie 
-<​code>​ 
-Welcome, <​nume-utilizator>,​ to Pearson-Hardman-Specter. <​nume-utilizator>​ just got Litt-up! 
-</​code>​ 
-unde ''<​nume-utilizator>''​ este username-ul. 
- 
-Pentru aceasta va trebui să editați, ca ''​root''​ (adică folosind ''​sudo''​),​ fișierul ''/​etc/​bash.bashrc''​ și să scrieți la **sfârșitul** fișierului comanda dorită. Comanda va fi rulată la orice deschidere de shell nou. Folosiți comanda ''​sudo vim /​etc/​bash.bashrc''​ pentru a edita ca root fișierul ''/​etc/​bash.bashrc''​. 
- 
-<​note>​ 
-Fișierul ''/​etc/​bash.bashrc''​ este un fișier global de configurare a shell-ului. Fișierul este parcurs la fiecare deschidere de shell. 
-</​note>​ 
- 
-Pentru început afișați șirul ''​%%Welcome%%''​ la fiecare deschidere de shell. Adică scrieți la sfârșitul fișierului ''/​etc/​bash.bashrc''​ comanda pentru afișarea șirului. Apoi deschideți un shell nou (sau un tab nou de shell pentru verificare). 
- 
-<note tip> 
-Pentru a afișa un mesaj folosiți comanda ''​echo''​ urmată de șirul de afișat. Este recomandat ca șirul de afișat, transmis ca argument comenzii ''​echo''​ să fie pus între ghilimele (''​%%"​%%'',​ //​quotes//​). 
-</​note>​ 
- 
-Pentru afișarea șirului dorit, care conține username-ul,​ folosiți variabila ''​USER'',​ variabilă deja definită în shell. Variabila ''​USER''​ conține username-ul. Pentru a afișa valoarea unei variabile folosim construcția de forma ''​$USER''​. De exemplu, pentru a afișa numele de utilizator și un mesaj de salut folosim comanda 
-<​code>​ 
-echo "​Salut,​ $USER" 
-</​code>​ 
- 
-<​solution>​ 
-<code bash> 
-sudo echo 'echo "​Welcome,​ $USER, to Pearson-Hardman-Specter. $USER just got Litt-up!"'​ >> /​etc/​bash.bashrc 
-</​code>​ 
- 
-Sau se adauga comanda <code bash> echo "​Welcome,​ $USER, to Pearson-Hardman-Specter. $USER just got Litt-up!"​ </​code>​ pe orice linie care nu se afla sub un ''​if''​ in fisierul ''/​etc/​bash.bashrc''​ 
-</​solution>​ 
- 
-==== [3] Căutare de fișiere (2p) ==== 
- 
-De multe ori dorim să căutăm într-o ierarhie de fișiere și directoare, dar după anumite criterii. Comanda cea mai potrivită în acest caz este ''​find''​. Folosiți ''​find''​ pentru a afișa toate fișierele din ierarhia ''/​etc/''​ (adică toate fișierele din /etc/, din subdirectoarele acestuia, din subdirectoarele subdirectoarelor etc.). **Hint**: Folosiți opțiunea ''​-type''​ a comenzii find. 
- 
-Extindeți comanda anterioară pentru a afișa toate fișierele din ierarhia ''/​etc/''​ al căror nume începe cu litere între //a// și //d//. **Hint**: Folosiți opțiunea ''​-name''​ a comenzii find și construcția ''​[a-d]*''​ pentru a indica un șir care începe cu o literă între //a// și //d// urmată de orice altceva. 
- 
-Extindeți comanda anterioară pentru a afișa toate fișierele din ierahia ''/​etc/''​ care au permisiunile de forma ''​%%rw-------%%'',​ adică 600. **Hint**: Folosiți opțiunea ''​-perm''​ urmată de permisiunile căutate în format octal. 
- 
-Pentru comanda finală, redirectați outputul în fișierul ''​~/​file_list.txt''​ și erorile în ''​~/​errors.txt''​. 
- 
-<​solution>​ 
-Comanda finala: ​ 
- 
-<code bash> 
-find /etc -type f -name "​[a-d]*"​ -perm 600 2> ~/​errors.txt > ~/​file_list.txt 
-</​code>​ 
-</​solution>​ 
-==== [4] Lucrul cu arhive tar (2p) ==== 
- 
-<note important>​ 
-Luați exercițiul pe bucăți, faceți o parte apoi treceți la următoarea. 
-</​note>​ 
- 
-Descărcați arhiva {{:​uso:​laboratoare:​practic.tar.gz|de aici}} folosind una dintre comenzile ''​wget''​ sau ''​curl''​. 
- 
-<note tip> 
-Atât ''​wget''​ cât și ''​curl''​ primesc ca parametru un URL (link). URL-ul îl puteți obține folosind, în browser, click dreapta și selectând opțiunea ''​Copy link location''​. Pentru a da paste în terminal folosiți click dreapta și selectând ''​Paste'',​ sau, mai direct, combinația de taste ''​Shift+Insert''​. Dacă alegeți să folosiți ''​curl'',​ fiți atenți la faptul că, implicit, acesta afișează conținutul fișierului pe ecran, deci va trebui să-l redirectați voi într-un fișier ''​practic.tar.gz''​. 
-</​note>​ 
- 
-<​solution>​ 
-<code bash> 
-wget http://​ocw.cs.pub.ro/​courses/​_media/​uso/​laboratoare/​practic.tar.gz 
-</​code>​ 
-</​solution>​ 
- 
-  * Fără a o dezarhiva, listați conținutul arhivei ''​practic.tar.gz''​. (**Hint**: Folosiți opțiunea ''​-t''​ a comenzii ''​tar''​). 
- 
-<​solution>​ 
-<code bash> 
-tar -tf practic.tar.gz 
-</​code>​ 
-</​solution>​ 
- 
-  * Dezarhivați arhiva ''​practic.tar.gz''​. (**Hint**: Arhiva este în format ''​.tar.gz''​. Pentru a afla comanda de dezarhivare căutați pe Google șirul ''​unpack .tar.gz''​. După dezarhivare directorul obținut este ''​practic/''​.) 
- 
-<​solution>​ 
-tar -xvf practic.tar.gz 
-</​solution>​ 
-==== [5] Globbing (2p) ==== 
- 
-Listați, folosind **globbing**,​ toate imaginile cu extensiile ''​bmp,​ jpg, png, gif''​ din directorul rezultat în urma dezarhivării. 
- 
-<note tip> 
-Parcurgeți secțiunea [[#​globbing|Globbing]] din cadrul laboratorului. 
- 
-Pentru a lista toate fișierele cu extensiile ''​bmp'',​ ''​jpg'',​ ''​png''​ și ''​gif''​ folosiți operatorii de globbing ''​*''​ (//star//) si ''​{opt1,​opt2,​opt3}''​ (acolade). Un exemplu simplu de utilizare (porniți de la acesta) este 
-<​code>​ 
-ls practic/​*/​*.png 
-</​code>​ 
-În comanda de mai sus listăm toate fișierele cu extensia ''​png''​ din toate subdirectoarele directorului ''​practic''​. 
-</​note>​ 
- 
-Redirectați outputul într-un fișier numit ''​images.dat''​. 
- 
-<​note>​ 
-Pentru redirectare într-un fișier folosiți operatorul ''>''​. 
-</​note>​ 
- 
-<​solution>​ 
-<​code>​ 
-mihai@wormhole:​~$ ls practic/​*/​*.{bmp,​jpg,​png,​gif} > images.dat 
-mihai@wormhole:​~$ cat images.dat 
-practic/​a/​showmeyes.gif 
-practic/​b/​britney.jpg 
-practic/​c/​landscape.png 
-practic/​d/​trickynot.bmp 
- 
-</​code>​ 
-</​solution>​ 
- 
-Ștergeți directorul dezarhivat folosind comanda 
-<​code>​ 
-rm -fr practic/ 
-</​code>​ 
- 
-==== [Bonus #1] Lucrul cu arhive tar - continuare (1 karma WoUSO) ==== 
- 
-Extrageți din arhiva ''​practic.tar.gz''​ **doar** fișierele listate în fișierul ''​images.dat''​. 
- 
-<note tip> 
-Pentru a afla opțiunile ''​tar''​ de extragere doar a anumitor fișiere dintr-o arhivă, căutați pe Google șirul ''​tar extract specific files''​. 
- 
-În cadrul comenzii porniți de la exemplul de mai jos care listează în format lung fișierele indicate în fișierul ''​images.dat'':<​code>​ 
-ls -l $(cat images.dat) 
-</​code>​ 
-Comanda va da eroare pentru că directorul ''​practic/''​ nu mai există, dar sintaxa este corectă și o puteți adapta pentru comanda ''​tar''​. Adică să aveți o comandă de forma<​code>​ 
-tar ... $(cat images.dat) 
-</​code>​ 
- 
-Pentru verificarea dezarhivării doar a fișierelor de tip imagine folosiți comanda<​code>​ 
-tree practic/ 
-</​code>​ 
-</​note>​ 
- 
-<​solution><​code bash> 
-mihai@wormhole:​~$ cat images.dat 
-practic/​a/​showmeyes.gif 
-practic/​b/​britney.jpg 
-practic/​c/​landscape.png 
-practic/​d/​trickynot.bmp 
-mihai@wormhole:​~$ tar -xf practic.tar.gz $(cat images.dat) ​     ​ 
-mihai@wormhole:​~$ tree practic 
-practic 
-├── a 
-│   └── showmeyes.gif 
-├── b 
-│   └── britney.jpg 
-├── c 
-│   └── landscape.png 
-└── d 
-    └── trickynot.bmp 
- 
-4 directories,​ 4 files 
- 
-</​code>​ 
-</​solution>​ 
- 
-==== [Bonus #2] Lucrul cu arhive tar - continuare (1 karma WoUSO) ==== 
- 
-Creați un script numit ''​extract-images-only.sh''​ care să conțină comenzile folosite la cele 3 exerciții precedente. Acordați permisiuni de execuție și rulați scriptul. Scriptul va trebui să: 
-  * dezarhiveze arhiva ''​practic.tar.gz''​ 
-  * listeze toate fișierele cu una dintre extensiile //png//, //jpg//, //bmp// sau //gif// în fișierul **images.dat**. Fișierul **images.dat** va trebui suprascris de fiecare dată. 
-  * șteargă directorul ''​practic''​ 
-  * dezarhiveze din arhiva ''​practic.tar.gz''​ doar fișierele aflate în fișierul ''​images.dat''​ 
-  * listeze conținutul directorului ''​practic''​ pe ecran, folosind comanda ''​tree''​. 
- 
-<note tip> 
-Parcurgeți secțiunea [[#​shell_scripting|Shell Scripting]] din cadrul laboratorului. 
- 
-Scriptul trebuie să înceapă cu shebang adică șirul ''#​!/​bin/​bash''​. 
- 
-Pentru acordarea permisiunilor de execuție folosiți comanda ''​chmod''​. 
-</​note>​ 
- 
-<​solution>​ 
-<code bash extract-images-only.sh>​ 
-#!/bin/bash 
- 
-wget http://​ocw.cs.pub.ro/​courses/​_media/​uso/​laboratoare/​practic.tar.gz 
- 
-tar -zxf practic.tar.gz 
- 
-ls practic/​*/​*.{png,​jpg,​gif,​bmp} >> images.dat 
-rm -fr practic/ 
- 
-tar -zxf practic.tar.gz $(cat images.dat) 
-tree practic/ 
-</​code>​ 
- 
-<code bash> 
-student@midgard:​~$ pwd 
-/​home/​student 
-student@midgard:​~$ chmod +x extract-images-only.sh 
-student@midgard:​~$ ./​extract-images-only.sh 
-(...) 
-</​code>​ 
- 
-</​solution>​ 
- 
-==== [Bonus #3] Folosirea shell operators (1 karma WoUSO) ==== 
- 
-Uneori putem testa rezultatul execuției unei comenzi folosind una dintre construcțiile următoare: ​ 
-<code bash> 
-student@uso:​~$ comanda && echo "​SUCCESS"​ 
-</​code>​ 
-sau 
-<code bash> 
-student@uso:​~$ comanda || echo "​FAIL"​ 
-</​code>​ 
- 
-Pe baza conținutului celor două fișiere create la [[http://​ocw.cs.pub.ro/​courses/​uso/​laboratoare/​laborator-06#​cautare_de_fisiere_1p|Exercițiul 3]], ''​file_list.txt''​ și ''​errors.txt'',​ scrieți un one liner care afișează pe ecran textul ''​SUCCESS'',​ dacă nu s-a produs nicio eroare la folosirea comenzii ''​find''​ (fișierul ''​errors.txt''​ este gol) sau ''​FAILED WITH <​num_erori>​ ERRORS'',​ unde ''<​num_erori>''​ este numărul de linii (erori) din fișierul ''​errors.txt''​. 
- 
-<note tip> 
-Considerăm că orice linie din fișierul ''​errors.txt''​ reprezintă o eroare separată. Pentru a calcula numărul de linii dintr-un fișier ''​a.txt''​ putem folosi comanda<​code>​ 
-student@uso:​~$ wc -l < a.txt 
-</​code>​ 
-</​note>​ 
- 
-<note tip> 
-Pentru a verifica dacă fișierul ''​errors.txt''​ are conținut (are dimensiunea mai mare ca ''​0''​),​ folosiți comanda 
-<​code>​ 
-test -s errors.txt 
-</​code>​ 
-Această comandă se întoarce cu succes dacă fișierul are conținut (are dimensiunea mai mare ca ''​0''​). Adică puteți să folosiți în continuarea comenzii de mai sus operatorii ''&&''​ și ''​||''​ pentru a afișa un mesaj de succes sau de insucces. 
- 
-Ca să expandați numărul de linii din cadrul unui fișier folosiți o construcție de forma ''​$(wc -l < a.txt)''​. 
-</​note>​ 
- 
-==== [Bonus #4] User & Password generator (2 karma WoUSO) ==== 
- 
-Unui script îi putem da și argumente în linia de comandă. Urmăriți scriptul exemplu de mai jos: 
- 
-<code bash args.sh> 
-#!/bin/bash 
- 
-echo "​Numarul argumentelor este $#" 
-echo "​Numele scriptului este $0" 
-echo "​Primele 2 argumente sunt: $1 \\ $2" 
-</​code>​ 
- 
-<code bash> 
-student@midgard:​~$ chmod +x args.sh 
-student@midgard:​~$ ./args.sh 1 2 3 4 5 
-Numarul argumentelor este 5 
-Numele scriptului este ./args.sh 
-Primele 2 argumente sunt: 1 \ 2 
-</​code>​ 
- 
-Realizați un script numit ''​simple_adduser.sh''​ care adaugă în sistem utilizatorul U, îi configurează homedir-ul la ''/​home/​U''​ și îi generează o parolă de ''​N''​ caractere, unde ''​N''​ este dat ca argument scriptului. 
- 
-Scriptul va fi chemat astfel: ''​./​simple_adduser.sh username 20''​ 
- 
-La final trebuie să afișați un string de forma: ''​Utilizator:​parola_generata''​ 
- 
-<note tip>​Indicații: ​ 
-Pentru adăugarea neinteractivă a utilizatorilor în sistem, folosiți comanda ''​useradd''​ 
- 
-Parola generată o salvați într-o variabilă. Pentru un utilizator existent în sistem, putem configura o parolă neinteractiv folosind ''​chpasswd''​ astfel: ​ 
- 
-<code bash> 
-echo "​user:​newpassword"​ | chpasswd 
-</​code>​ 
- 
-</​note>​ 
- 
-<​solution>​ 
-<code bash simple_adduser.sh>​ 
-#!/bin/bash 
- 
-NUM_CHARS=$2 
-USERNAME=$1 
- 
-useradd $USERNAME -d /​home/​$USERNAME -s /bin/bash && mkdir /​home/​$USERNAME 
- 
-PASSWORD=$(cat /​dev/​urandom | tr -d -c '​A-Za-z0-9'​ | head -c $NUM_CHARS) 
- 
-echo "​$USERNAME:​$PASSWORD"​ 
-echo "​$USERNAME:​$PASSWORD"​ | chpasswd 
-</​code>​ 
-</​solution>​ 
- 
-==== [Bonus #5] Sleeping processes (1 karma WoUSO) ==== 
- 
-Folosiți un one-liner pentru a determina PID-ul și comanda tuturor proceselor din sistem aflate în starea ''​sleeping''​. Indicație: ''​man ps'',​ ''/​user-defined format'' ​ 
- 
-Folosiți un one-liner pentru a determina câte procese sunt în starea ''​sleeping''​. Indicație: folosiți comanda utilizată anterior și dați outputul ca parametru (prin pipe sau ca variabilă) lui ''​wc''​ (word count) cu un anumit parametru. ​ 
- 
-<​solution>​ 
-O potentiala solutie 
- 
-<code bash> 
-ps -eo state,​command,​pid | grep "​^[SD]"​ | wc -l 
-</​code>​ 
-</​solution>​ 
- 
-==== [Bonus #6] Variabila $PATH (1 karma WoUSO) ==== 
- 
-Creați directorul ''/​home/​student/​executables/''​. Plasați scriptul ''​extract-images-only.sh'',​ creat la [[http://​ocw.cs.pub.ro/​courses/​uso/​laboratoare/​laborator-06#​lucrul_cu_arhive_tar_-_continuare_1p1|Exercițiul 8]] în acest director și redenumiți-l în ''​extract-images-only''​ (fără ''​.sh''​). Configurați sistemul astfel încât să putem executa scriptul direct, fără a folosi calea către acesta (așa cum executăm ''​ls'',​ de exemplu). La final veți putea rula scriptul doar cu ajutorul comenzii<​code>​ 
-extract-images-only 
-</​code>​ 
- 
-<note tip> 
-Va trebui să actualizați valoarea variabilei de mediu ''​PATH'',​ variabilă ce conține căile către **directoarele** ce conțin executabile/​scripturi care sunt rulate direct. Adică va trebui să adăugați în cadrul variabilei ''​PATH''​ directorul ''/​home/​student/​executables/''​. 
- 
-Pentru documentare despre cum puteți actualiza valoarea variabilei de mediu ''​PATH''​ urmăriți [[http://​www.cyberciti.biz/​faq/​unix-linux-adding-path/​|acest link]]. 
-</​note>​ 
- 
-<​solution>​ 
-<​code>​ 
-student@midgard:​~$ mv extract-images-only.sh /​home/​student/​executables/​extract-images-only 
-student@midgard:​~$ export PATH=$PATH:/​home/​student/​executables/​ 
-student@midgard:​~$ extract-images-only 
-</​code>​ 
- 
-</​solution>​ 
- 
-==== [Bonus #7] Log inspection (3 karma WoUSO) ==== 
- 
-În fișierul ''/​var/​log/​syslog''​ se găsesc jurnalizate mai multe mesaje printre care și mesajele afișate de clientul de DHCP, numit ''​dhclient''​. Acest fișier îl afișați folosind ''​less''​. 
- 
-<note important>​ 
-Evitați să deschideți fișiere de jurnalizare folosind ''​vim'',​ din cauza faptului că logul poate fi foarte mare și vă poate bloca pentru secunde bune terminalul. Întotdeauna,​ inspectați logurile cu ''​less'',​ ''​tail'',​ ''​grep | less''​ etc. 
-</​note>​ 
- 
-După ce ați observat formatul datelor din fișierul ''/​var/​log/​syslog'',​ scrieți un one-liner care afișează pe ecran adresele IP care au fost furnizate de clientul de DHCP (adică acele mesaje care conțin șirul ''​bound to''​). 
- 
- 
-  
uso/laboratoare/laborator-06.1479241930.txt.gz · Last modified: 2016/11/15 22:32 by cstaniloiu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0