= Comunicare între resurse = [[https://docs.google.com/presentation/d/1ugVHI-t18A_9rTiPNCKgCgKF5tdrvvDwlSAQlNzvTwQ/pub?start=false&loop=false&delayms=3000|Slide-uri de prezentare]] == Tutorial (1) == === Descriptori de fișiere === * Aflați ''PID''-ul procesului bash ce rulează în terminal. ** hint: capitolul trecut * Intrați în directorul ''/proc/PID'', unde ''PID'' este cel aflat anterior. ** Ce reprezintă acest director? * Intrați în directorul ''fd''. Listați conținutul în format lung. ** Ce reprezintă output-ul? * Rulați comanda ''ps'' fără niciun argument. ** Ce reprezintă ''pts/0''? Fiecare terminal deschis în interfața grafică este de fapt un pseudo-terminal. Link-urile simbolice din directorul fd duc către device-ul corespunzător pseudo-terminal-ului. === Redirectări === * Rulați comanda ''yes a''. ** Într-un alt terminal rulați comanda ''ls -l /proc/`pidof yes`/fd''. *** Ce observați? Intrare și ieșirile standard. * Opriți comanda ==== Redirecționarea output-ului ==== * Rulați comanda ''echo > my_out_file''. ** Listați fișierele din directorul curent în format lung. Este creat un fișier nou. *Rulați comanda ''yes > a''. ** Într-un alt terminal rulați comanda ''ls -l /proc/`pidof yes`/fd''. *** Ce observați? *** Dacă se întâmplă acest lucru, ștergeți fișierul ''a'' și repetați task-ul. Ieșirea standard este redirecționată. * Rulați comanda ''echo Text > a''. ** Afișați conținutul fișierului ''a''. *** Folosiți comanda ''cat''. *** Ce s-a întâmplat cu acesta? Fișierul a fost suprascris. * Rulați comanda ''echo File >> a''. ** Afișați conținutul fișierului ''a''. *** Ce s-a întâmplat cu acesta? Fișierul nu a mai fost suprascris. Textul a fost adăugat la final. * Rulați comanda ''yes > /dev/null''. ** Într-un alt terminal, afișați conținutul fișierului ''/dev/null''. *** Ce observați? /dev/null este folosit pentru a redirecționa output-ul (a îl face să nu mai apară pe ecran) și a îi face drop. Se evită practic scrierea acestuia într-un fișier care ocupă spațiu pe hard. * Rulați comanda ''ls -l /proc/`pidof yes`/fd''. ** Ce observați? Ieșirea standard este redirecționată spre /dev/null. ==== Redirecționarea input-ului ==== *Rulați comanda ''read var''. ** Tastați ''thales'' apoi ''enter''. *Ce face comanda ''echo $var''? read citește de la tastatură text și îl salvează în variabila var. Comanda echo $var afișează conținutul variabilei. În acest caz afișează textul citit anterior. * Afișați din nou conținutul fișierului ''a''. * Rulați comanda ''(read var) < a''. ** ''a'' este fișierul de la task-ul anterior * Rulați din nou comanda ''echo $var''. ** Ce observați? Comanda de citire nu a mai așteptat comenzi de la tastatură și a citit din fișierul a. ==== Redirecționarea erorilor ==== * Rulați comanda ''ls > out''. ** Afișați conținutul fișierului ''out''. Output-ul comenzii ls a fost redirecționat în fișierul out. * Rulați comanda ''reboot > out''. ** Afișați conținutul fișierului ''out''. *** Ce observați? Comanda reboot dă eroare din cauza permisiunilor insuficiente. Se încearcă redirectarea output-ului în fișierul out, însă fișierul este suprascris și gol (deoarece nu se scrie nimic). Pe ecran apare mesajul scris la stderr de eroare. * Rulați comanda ''reboot &> out''. ** Afișați conținutul fișierului ''out''. *** Ce observați? Pe ecran nu mai apare eroarea. Aceasta a fost redirecționată împreună cu ieșirea standard în fișierul out. * Rulați comanda ''ls &> out''. ** Afișați conținutul fișierului ''out''. *** Ce observați? Operatorul redirecționează și standard output și standard error. * Rulați comanda ''(ls > /dev/tty) &> out''. *** Ce observați? Se încearcă redirecționarea erorilor în fișierul out. Cum nu se produce nicio eroare, fișierul out o să fie gol, iar pe ecran o să apară output-ul comenzii ls. == Tutorial (2) == === Pipe-uri cu nume === * Rulati comanda ''mkfifo my_pipe''. ** Listați fișierele din directorul curent în format lung. * Folosind comanda ''echo'', scrieți ceva în fișierul ''my_pipe''. ** hint: redirectare ** Ce observați? Terminal-ul se blochează. Comanda nu se termină. * Deschideți un alt terminal. ** Afișați conținutul fișierului ''my_pipe''. *** Ce observați? Apare textul scris mai devreme în pipe. * Ce s-a întâmplat în primul terminal? Primul terminal se deblochează * Încercați să afișați din nou conținutul fișierului ''my_pipe''. ** Ce observați? Comanda se blochează. Pipe-ul cu nume nu reține date pe disk. Terminalul va rămâne agățat până când un alt proces va scrie în pipe. * Într-un alt terminal, folosiți din nou comanda ''echo'' pentru a scrie ceva în fișier. ** Ce observați? (în ambele terminale) Terminalele se deblochează. Textul a ajuns dintr-o parte în alta. * Scrieți ceva în fișierul ''my_pipe'' folosind comanda ''echo''. ** Închideți terminalul și deschideți un nou terminal. ** Afișați conținutul fișierului. *** Ce observați? Închiderea terminal-ului a distrus mesajul din buffer-ul pipe-ului. (buffer-ul nu este persistent) === Pipe-uri anonime === * Rulați comanda ''ls | cat''. ** Ce observați? Comanda cat primește ca input output-ul comenzii ls și îl afișează pe ecran. * Rulați comanda ''ls | cat | cat | cat | cat ''. ** Ce observați? Același lucru. * Rulați comanda ''ls -l | less''. ** Ce observați? ** Navigați similar ca în paginile de manual. less te ajută să vizualizezi mai facil un output de dimensiune mare. * Rulați comanda ''ls -lR / | less''. * Rulați comanda ''ls -l | grep rwx''. ** Ce observați? ** Încercați să rulați o comandă asemănătoare care face match pe linile care nu conțin grupul ''rwx''. grep filtrează input-ul primit după un anumit pattern. În acest caz afișează linile ce conțin gruparea "rwx" * Rulați comanda ''cat /proc/cpuinfo | less''. ** Ce informații puteți afla? Informații despre procesor. * Rulați comanda ''ls -a | grep bash''. ** Ce observați? ** Ce fac fișierele identificate? Fișier ascuns de history. * Folosiți comanda **ls** și comanda **wc** pentru a afla numărul de intrări din directorul curent. ** hint: man pages ls -l | wc -l wc -l: numără câte linii există în input-ul primit == Exerciții == * Folosiți comanda ''yes'' pentru a scrie într-un fișier. ** hint: Redirectări ** Încercați să vizualizați conținutul fișierului. *Rulați comanda gedit. Închideți terminal-ul. Ce s-a întâmplat? **Folosiți comanda nohup astfel încât la închiderea terminalului, editorul text să nu se închidă. *Folosiți comanda ''trap'' pentru a scrie ceva în fișierul ''/tmp/file.log'' la închiderea terminalului. ** hint: SIGHUP ** ''man bash'' și /trap == Recapitulare == === Afișare procese === Dorim să afișăm anumite procese într-o anumită ordine. Folosiți ''ps'' cu opțiunea corectă pentru a afișa procesele care aparțin utilizatorului ''student''. Căutați în pagina de manual după șirul //user//. Pentru procesele de mai sus afișați PID-ul, comanda completă (cale completă cu parametri), timpul de rulare pe procesor, memoria RAM consumată (RSS -- //resident set size//). Pentru a selecta doar anumite atribute ale unui proces folosiți comanda ''ps'' cu parametrul ''-o'' urmat de opțiunile specifice; urmăriți și pagina de manual. Sortați procesele de mai sus în ordinea inversă a memoriei RAM consumate (RSS -- //resident set size//). Adică cele mai consumatoare de memorie procese la început. Din procesele sortate rețineți doar primele 10 intrări. Să afișați și antetul oferit de ''ps''. === Procesele unui utilizator === Dorim să lucrăm cu grupuri de procese care țin de un utilizator. Pe un tab nou de terminal adăugăm utilizatorul ''ana'' folosind comenzile $ sudo su # adduser ana [...] # exit # sau puteti folosi combinatia de taste Ctrl+d $ În acel tab nou ne autentificăm ca utilizatorul ''ana'' folosind comanda $ su - ana În cel nou tab, din contul utilizatorului ''ana'', porniți în background mai multe procese: ''sleep'', ''emacs'', ''gedit''. Din primul tab, folosiți, ca ''root'', ''pkill'' pentru o încheia execuția proceselor utilizatorului ''ana''; adică rulați ''sudo pkill ...'' (cu ce opțiuni sunt utile). Este posibil să fie necesar să folosiți semnalul ''SIGKILL'' ca să fie garantată încheierea execuției. === Procesele unui terminal === Pe un tab nou de terminal porniți în background procese ca utilizatorul ''root'', ''student'' și ''ana''. În acel tab aflăm care este identificatorul terminalului curent folosind comanda $ tty Din primul tab, folosiți, ca ''root'', ''pkill'' pentru o încheia execuția proceselor de pe al doilea terminal; adică rulați ''sudo pkill ...'' (cu ce opțiuni sunt utile). Este posibil să fie necesar să folosiți semnalul ''SIGKILL'' ca să fie garantată încheierea execuției. === Procese detașate de terminal === Sunt cazuri în care dorim să pornim procese detașate de terminal. Adică după pornirea procesului să închidem terminalul și procesul să nu fie "omorât" ci să își încheie execuția. Aceste procese sunt echivalente unor procese daemon. Pentru a detașa un proces de un terminal se folosesc comenzi precum ''nohup'', ''dtach'' și ''disown''. Folosiți comanda ''wget'' pentru a descărca fișierul ''.torrent'' de [[http://swarm.cs.pub.ro/~razvan/lin-prog.torrent|aici]]. ==== disown ==== Porniți un proces ''BitTorrent'' folosind comanda: btdownloadheadless lin-prog.torrent Transferați procesul pornit în starea de rulare în background. Detașați procesul de terminal folosind comanda ''disown''. Închideți terminalul. Investigați prezența procesului în alt terminal. Folosiți comanda ''lsof'' pentru a vedea ce folosește procesul pe post de standard input, standard output și standard error. Apoi încheiați execuția acelui proces. ==== nohup ==== Creați un proces BitTorrent precum cel de mai sus, detașat de terminal, folosind comanda ''nohup''. Închideți terminalul. Investigați prezența procesului în alt terminal. Folosiți comanda ''lsof'' pentru a vedea ce folosește procesul pe post de standard input, standard output și standard error.