Differences

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

Link to this comparison view

uso:laboratoare:laborator-07:improve-shell [2021/11/16 00:44]
mihai_daniel.soare [Încheierea execuției unei comenzi]
uso:laboratoare:laborator-07:improve-shell [2021/11/22 17:27] (current)
andreia.ocanoaia [Execuția comenzilor]
Line 43: Line 43:
 Pentru a înlănțui comenzi în terminalul bash avem trei operatori disponibili:​ Pentru a înlănțui comenzi în terminalul bash avem trei operatori disponibili:​
  
-Operatorul ''​%%;​%%''​ care este folosit pentru separarea comenzilor. Urmăm exemplul de mai jos:+  * Operatorul ''​%%;​%%''​ care este folosit pentru separarea comenzilor. Urmăm exemplul de mai jos:
 <code bash> <code bash>
 student@uso:​~$ mkdir demo; cd demo; touch Hello; ls student@uso:​~$ mkdir demo; cd demo; touch Hello; ls
Line 49: Line 49:
 </​code>​ </​code>​
 În exemplul de mai sus am creat directorul ''​%%demo%%'',​ am navigat în interiorul său, am creat fișierul ''​%%Hello%%''​ și am afișat conținutul directorului. Am făcut toate acestea înlănțuind comenzile ''​%%mkdir%%'',​ ''​%%cd%%'',​ ''​%%touch%%''​ și ''​%%ls%%''​ cu ajutorul operatorului ''​%%;​%%''​. În exemplul de mai sus am creat directorul ''​%%demo%%'',​ am navigat în interiorul său, am creat fișierul ''​%%Hello%%''​ și am afișat conținutul directorului. Am făcut toate acestea înlănțuind comenzile ''​%%mkdir%%'',​ ''​%%cd%%'',​ ''​%%touch%%''​ și ''​%%ls%%''​ cu ajutorul operatorului ''​%%;​%%''​.
 +
 Operatorul ''​%%;​%%''​ este folosit pentru separarea comenzilor, dar nu ține cont dacă comenzile anterioare au fost executate cu succes sau nu. Urmăm exemplul de mai jos: Operatorul ''​%%;​%%''​ este folosit pentru separarea comenzilor, dar nu ține cont dacă comenzile anterioare au fost executate cu succes sau nu. Urmăm exemplul de mai jos:
 <code bash> <code bash>
Line 56: Line 57:
 </​code>​ </​code>​
 <​HTML><​p></​HTML>​În exemplul de mai sus, comanda ''​%%mkdir%%''​ a eșuat deoarece nu a găsit directorul ''​%%operators%%''​ în care să creeze directorul ''​%%demo%%''​. Cu toate acestea, operatorul ''​%%;​%%''​ doar separă comenzile între ele, așa că și comanda ''​%%cd operators/​demo%%''​ a fost executată, și și aceasta a eșuat deoarece nu există calea ''​%%operators/​demo%%''​.<​HTML></​p></​HTML>​ <​HTML><​p></​HTML>​În exemplul de mai sus, comanda ''​%%mkdir%%''​ a eșuat deoarece nu a găsit directorul ''​%%operators%%''​ în care să creeze directorul ''​%%demo%%''​. Cu toate acestea, operatorul ''​%%;​%%''​ doar separă comenzile între ele, așa că și comanda ''​%%cd operators/​demo%%''​ a fost executată, și și aceasta a eșuat deoarece nu există calea ''​%%operators/​demo%%''​.<​HTML></​p></​HTML>​
 +
 <​HTML><​p></​HTML>​Folosim operatorul ''​%%;​%%''​ pentru a înlănțui comenzi care sunt independente unele de altele, și deci execuția lor nu depinde de succesul unei comenzi precedente.<​HTML></​p></​HTML><​HTML></​li></​HTML>​ <​HTML><​p></​HTML>​Folosim operatorul ''​%%;​%%''​ pentru a înlănțui comenzi care sunt independente unele de altele, și deci execuția lor nu depinde de succesul unei comenzi precedente.<​HTML></​p></​HTML><​HTML></​li></​HTML>​
-<​HTML><​li></​HTML><​HTML><​p></​HTML>​Operatorul binar ''​%%&&​%%''​ (și logic) - execută a doua comandă doar dacă precedenta s-a executat cu succes. Exemplul anterior devine:<​HTML></​p></​HTML>​+ 
 +  
 +  * Operatorul binar ''​%%&&​%%''​ (și logic) - execută a doua comandă doar dacă precedenta s-a executat cu succes. Exemplul anterior devine:
 <code bash> <code bash>
 student@uso:​~$ mkdir operators/​demo && cd operators/​demo student@uso:​~$ mkdir operators/​demo && cd operators/​demo
Line 63: Line 67:
 </​code>​ </​code>​
 <​HTML><​p></​HTML>​Observăm că din moment ce comanda ''​%%mkdir%%''​ a eșuat, comanda ''​%%cd%%''​ nu a mai fost executată.<​HTML></​p></​HTML><​HTML></​li></​HTML>​ <​HTML><​p></​HTML>​Observăm că din moment ce comanda ''​%%mkdir%%''​ a eșuat, comanda ''​%%cd%%''​ nu a mai fost executată.<​HTML></​p></​HTML><​HTML></​li></​HTML>​
-* Operatorul binar ''​%%||%%''​ (sau logic) - execută a doua comandă doar dacă prima s-a terminat cu eșec. Urmărim exemplul de mai jos:+  ​* Operatorul binar ''​%%||%%''​ (sau logic) - execută a doua comandă doar dacă prima s-a terminat cu eșec. Urmărim exemplul de mai jos:
 <code bash> <code bash>
 student@uso:​~$ (ls -d operators || mkdir operators) && ls -d operators student@uso:​~$ (ls -d operators || mkdir operators) && ls -d operators
Line 83: Line 87:
 === Exerciții === === Exerciții ===
  
-  - Scrieți un oneliner cu ajutorul căruia creați directorul ''​%%~/​uso-lab/​labs/​05-cli/​support/​make-folder%%''​ și apoi copiați conținutul directorului ~/​uso-lab/​labs/​05-cli/​support/​redir în el. +  - Scrieți un oneliner cu ajutorul căruia creați directorul ''​%%~/​uso-lab/​labs/​05-cli/​support/​make-folder%%''​ și apoi copiați conținutul directorului ​''​%%~~/​uso-lab/​labs/​05-cli/​support/​redir%%'' ​în el. 
-  - Actualizați onelinerul anterior astfel încât după copiere să pornească compilarea proiectului folosind comanda ''​%%make ​build%%''​.+  - Actualizați onelinerul anterior astfel încât după copiere să pornească compilarea proiectului folosind comanda ''​%%make ​all%%''​.
  
 ==== Înlănțuirea comenzilor folosind operatorul | (pipe) ==== ==== Înlănțuirea comenzilor folosind operatorul | (pipe) ====
Line 149: Line 153:
 ==== Redirectări ==== ==== Redirectări ====
  
-Majoritatea utilitarelor pe care le folosim afișează rezultatele operațiilor pe care le aplică la ieșirea standard, adică pe ecran. În continuare vom aprofunda ceea ce am discutat despre redirectări în capitolul **Lucrul cu Fișiere**. Anterior am mai menționat și termenul de intrare standard; în această secțiune ne vom clarifica ce înseamnă, ce rol îndeplinesc și cum ne folosim de aceste cunoștințe.+Majoritatea utilitarelor pe care le folosim afișează rezultatele operațiilor pe care le aplică la ieșirea standard, adică pe ecran. În continuare vom aprofunda ceea ce am discutat despre redirectări în capitolul **Lucrul cu Fișiere**. Anterior am mai menționat și termenul de intrare standard; în această secțiune ne vom clarifica ce înseamnă, ce rol îndeplinesc și cum ne folosim de aceste cunoștințe. Acum, adăugăm câteva informații noi la ceea ce am învățat deja.
  
-Orice proces folosește implicit trei fluxuri (streams) de date:+Putem folosi niște fișiere speciale pentru redirectarea outputulu sau erorilor sau din care să citim input. Detaliem mai jos.
  
-  * **STDIN** - fluxul de intrare standard, referit și ca "citit de la tastatură"​. Spunem că un program care citește date de intrare din linie de comandă, deci așteaptă de la utilizator, citește de la intrarea standard; de aici și denumirea "citit de la tastatură"​. Complementul citirii de la tastatură este citirea datelor dintr-un fișier. 
-  * **STDOUT** - fluxul de ieșire standard, referit și ca "​afișare pe ecran"​. Spunem că un program afișează datele de ieșire pe ecran, adică scrie rezultatele procesărilor efectuate la ieșirea standard. Complementul afișării pe ecran este scrierea rezultatelor într-un fișier. 
-  * **STDERR** - fluxul de ieșire standard al erorilor. Un program corect scris o să scrie erorile în fluxul de ieșire al erorilor. Acest lucru permite filtrarea erorilor. 
- 
-În linie de comandă, atât STDOUT cât și STDERR vor apărea pe ecran. Datorită faptului că informațiile sunt scrise în două fluxuri distincte, utilizatorul are posibilitatea de a separa rezultatele de erori. Utilizatorul face aceasta folosind redirectări. 
- 
-=== Redirectarea ieșirilor standard === 
- 
-Cum spuneam mai sus, majoritatea programelor pe care le folosim vor afișa rezultatele pe ecran. Acest comportament este bun atunci când ne scriem onelinerul care ne extrage informațiile căutate, dar cel mai probabil o să vrem să salvăm rezultatul procesării într-un fișier. 
- 
-Folosim operatorul ''​%%>​%%''​ pentru a redirecta **STDOUT** sau **STDERR** într-un fișier. Pentru fiecare flux de date avem un număr, numit descriptor de fișier, asociat: 
- 
-  * **STDIN** are asociat descriptorul de fișier 0 
-  * **STDOUT** are asociat descriptorul de fișier 1 
-  * **STDERR** are asociat descriptorul de fișier 2 
- 
-Pentru a redirecta ieșirea standard folosim sintaxa ''​%%cmd 1> nume-fișier%%''​. Pentru a redirecta ieșirea standard a erorilor folosim sintaxa ''​%%cmd 2> nume-fișier%%''​. 
- 
-<note warning> 
- 
- 
-**Atenție!** În cazul în care fișierul destinație nu există, operatorul ''​%%>​%%''​ îl va crea. Dacă fișierul destinație există, operatorul ''​%%>​%%''​ va șterge conținutul acestuia. 
-</​note>​ 
- 
-Urmăm exemplul de mai jos: 
- 
-<code bash> 
-student@uso:​~$ ps -e -ouser,​uid,​pid,​%mem,​%cpu,​rss,​cmd --sort=-%mem | head -11 
-USER       ​UID ​  PID %MEM %CPU   RSS CMD 
-student ​  ​1000 ​ 7938 18.0  0.1 367952 /​usr/​bin/​gnome-shell 
-student ​  ​1000 ​ 8437  8.4  0.0 171916 /​usr/​bin/​gnome-software --gapplication-service 
-student ​  ​1000 ​ 7782  3.9  0.0 81312 /​usr/​lib/​xorg/​Xorg vt1 -displayfd 3 -auth /​run/​user/​1000/​gdm/​Xauthority -background none -noreset -keeptty -verbose 3 
-root         ​0 ​ 1338  3.8  0.0 78880 /​usr/​bin/​dockerd -H fd:// --containerd=/​run/​containerd/​containerd.sock 
-student ​  ​1000 ​ 8307  3.1  0.0 64628 /​usr/​lib/​evolution/​evolution-calendar-factory 
-student ​  ​1000 ​ 8338  3.0  0.0 61860 /​usr/​lib/​evolution/​evolution-calendar-factory-subprocess --factory all --bus-name org.gnome.evolution.dataserver.Subprocess.Backend.Calendarx8307x2 --own-path /​org/​gnome/​evolution/​dataserver/​Subprocess/​Backend/​Calendar/​8307/​2 
-root         ​0 ​  ​336 ​ 2.6  0.0 53612 /​lib/​systemd/​systemd-journald 
-student ​  ​1000 ​ 8274  2.3  0.0 48296 nautilus-desktop 
-root         ​0 ​ 1074  2.2  0.0 45460 /​usr/​bin/​containerd 
-student ​  1000 12966  1.8  0.0 38216 /​usr/​lib/​gnome-terminal/​gnome-terminal-server 
-student@uso:​~$ ps -e -ouser,​uid,​pid,​%mem,​%cpu,​rss,​cmd --sort=-%mem | head -11 1> top10-consumers 
-student@uso:​~$ less top10-consumers 
-</​code>​ 
-Am scris, prin încercări succesive, onelinerul care ne afișează primele zece procese care consumă cea mai multă memorie. Apoi am folosit sintaxa ''​%%1>​ top10-consumers%%''​ pentru a redirecta rezultatul în fișierul **top10-consumers**. 
- 
-Urmăm exemplul de mai jos pentru a redirecta erorile: 
- 
-<code bash> 
-student@uso:​~$ ls D* F* > out 2> errs 
-student@uso:​~$ cat out 
-Desktop: 
-todos.txt 
- 
-Documents: 
-snippets.git 
-uni 
-uso.tar 
- 
-Downloads: 
-courses.tar 
-uso.tar 
-student@uso:​~$ cat errs 
-ls: cannot access '​F*':​ No such file or directory 
-</​code>​ 
-Observăm că am folosit sintaxa ''​%%2>​ errs%%''​ pentru a redirecta erorile în fișierul **errs**. Observăm că pentru a redirecta ieșirea standard putem omite descriptorul de fișier, așa cum am făcut cu ''​%%>​ out%%''​. 
- 
-Atunci când rulăm o comandă, redirectăm erorile într-un fișier pentru că vrem să verificăm că totul s-a executat cu succes. De cele mai multe ori suntem în rumătorul scenariu: 
- 
-  - Urmează să executăm o comandă care durează mai mult timp și pentru care nu putem să ținem pasul, cu ochiul liber, cu fluxul de afișare a datelor pe ecran. Un exemplu este compilarea unui proiect mai mare. 
-  - O să pornim procesul și o să redirectăm STDOUT și STDERR în două fișiere, de ex. ''​%%out%%''​ și ''​%%err%%''​. 
-  - În timpul cât rulează noi putem să facem altceva: ne ocupăm de altă sarcină, ne facem o cafea, etc. 
-  - La finalul execuției inspectăm fișierele ''​%%out%%''​ și ''​%%err%%''​ pentru a vedea dacă au existat erori și le rezolvăm. 
- 
-<​note>​ 
- 
- 
-Acum înțelegem cum funcționează operatorul ''​%%|%%''​ (pipe). Acesta conectează fluxul de ieșire (STDOUT) al comenzii din stânga sa cu fluxul de intrare (STDIN) al comenzii din dreapta. 
-</​note>​ 
- 
-=== Redirectarea în mod append === 
- 
-Implicit, operatoru ''​%%>​%%''​ șterge (trunchează) conținutul fișierului destinație. Dacă vrem să păstrăm conținutul fișierului și să adăugăm rezultatul redirectării în continuarea acestuia, folosim operatorul ''​%%>>​%%''​. 
- 
-Rulați din nou exemplele de mai sus folosind operatorul ''​%%>>​%%''​ în locul operatorului ''​%%>​%%''​. Folosiți less pentru a inspecta fișierele de ieșire și de erori. 
  
 === Fișiere speciale === === Fișiere speciale ===
Line 241: Line 162:
 Pe sistemele Linux găsim un număr de fișiere speciale pe care le putem folosim în diferite scopuri: Pe sistemele Linux găsim un număr de fișiere speciale pe care le putem folosim în diferite scopuri:
  
-<​HTML><​ul></​HTML>​ +Fișierul ''​%%/​dev/​null%%''​ este un fișier care ignoră orice este scris în el. Este echivalentul unei găuri negre în sistemul nostru. Cu ajutorul său, putem rescrie exemplul de mai sus în modul următor:
-<​HTML><​li></​HTML><​HTML><​p></​HTML>​Fișierul ''​%%/​dev/​null%%''​ este un fișier care ignoră orice este scris în el. Este echivalentul unei găuri negre în sistemul nostru. Cu ajutorul său, putem rescrie exemplul de mai sus în modul următor:<​HTML></​p></​HTML>​+
 <code bash> <code bash>
 student@uso:​~$ firefox &> /dev/null & student@uso:​~$ firefox &> /dev/null &
Line 249: Line 169:
 [2] 10595 [2] 10595
 </​code>​ </​code>​
-<​HTML><​p></​HTML>​Acum orice va genera ''​%%firefox%%''​ va fi scris în ''​%%/​dev/​null%%'',​ care va consuma textul primit fără a ocupa spațiu pe disc.<​HTML></​p></​HTML><​HTML></​li></​HTML>​ +Acum orice va genera ''​%%firefox%%''​ va fi scris în ''​%%/​dev/​null%%'',​ care va consuma textul primit fără a ocupa spațiu pe disc. 
-<​HTML><​li></​HTML><​HTML><​p></​HTML>​Fișierul ''​%%/​dev/​zero%%''​ este un generator de octeți. Acesta generează atâția octeți cu valoarea zero (**0**)((<​HTML><​p></​HTML>​Valoarea **0** nu înseamnă cifra **0**. Valoarea **0** înseamnă caracterul **(null)** din tabelul [[http://​www.asciitable.com/​|ASCII]]. Caracterul **0** are valoarea **48** în tabelul ASCII.<​HTML></​p></​HTML>​)) cât îi sunt ceruți. Urmăm exemplul:<​HTML></​p></​HTML>​+Fișierul ''​%%/​dev/​zero%%''​ este un generator de octeți. Acesta generează atâția octeți cu valoarea zero (**0**)((Valoarea **0** nu înseamnă cifra **0**. Valoarea **0** înseamnă caracterul **(null)** din tabelul [[http://​www.asciitable.com/​|ASCII]]. Caracterul **0** are valoarea **48** în tabelul ASCII.)) cât îi sunt ceruți. Urmăm exemplul:
 <code bash> <code bash>
 student@uso:​~$ cat /dev/zero | xxd student@uso:​~$ cat /dev/zero | xxd
Line 265: Line 185:
 ^C ^C
 </​code>​ </​code>​
-<​HTML><​p></​HTML>​Deoarece citim din generator, comanda ''​%%cat%%''​ va afișa o infinitate de octeți cu valoarea zero. Utilitarul ''​%%xxd%%''​ afișează în hexazecimal textul primit la STDIN. Trecem rezultatul lui ''​%%cat%%''​ prin ''​%%xxd%%''​ deoarece valoarea **0** nu este un caracter printabil. Cu alte cuvinte nu este un caracter obișnuit, ca cele de pe tastatură, deoarece nu are un echivalent grafic. Folosim ''​%%Ctrl+c%%''​ pentru a opri execția.<​HTML></​p></​HTML>​ +Deoarece citim din generator, comanda ''​%%cat%%''​ va afișa o infinitate de octeți cu valoarea zero. Utilitarul ''​%%xxd%%''​ afișează în hexazecimal textul primit la STDIN. Trecem rezultatul lui ''​%%cat%%''​ prin ''​%%xxd%%''​ deoarece valoarea **0** nu este un caracter printabil. Cu alte cuvinte nu este un caracter obișnuit, ca cele de pe tastatură, deoarece nu are un echivalent grafic. Folosim ''​%%Ctrl+c%%''​ pentru a opri execția.**Exercițiu**:​ Rulați comanda ''​%%cat /​dev/​zero%%''​ pentru a înțelege nevoia utilitarului ''​%%xxd%%''​ din exemplul de mai sus. 
-<​HTML><​p></​HTML>​**Exercițiu**:​ Rulați comanda ''​%%cat /​dev/​zero%%''​ pentru a înțelege nevoia utilitarului ''​%%xxd%%''​ din exemplul de mai sus.<​HTML></​p></​HTML>​ +<note
-<HTML><​blockquote+De retinut, fișierul ''​%%/​dev/​urandom%%''​ este un alt generator de octeți ​pe care-l putem folosi pentru extragerea de caractere. De exemplu, pentru a genera o parola de 30 de caractere alfanumerice
-<​HTML><​ul></​HTML>​ + </note
-<​HTML><​li></​HTML>​Fișierul ''​%%/​dev/​urandom%%''​ este un alt generator de octeți.<​HTML></​li></​HTML><​HTML></​ul></​HTML>​ +Acesta generează atâția octeți cu valoare random cât îi sunt ceruți. 
-</blockquote></​HTML+ 
-<​HTML><​p></​HTML>​Acesta generează atâția octeți cu valoare random cât îi sunt ceruți.<​HTML></​p></​HTML>​ +  * **Exercițiu**:​ Rulați comenzile din exemplul anterior, dar acum citiți din ''​%%/​dev/​urandom%%''​.
-<​HTML><​p></​HTML>​**Exercițiu**:​ Rulați comenzile din exemplul anterior, dar acum citiți din ''​%%/​dev/​urandom%%''​.<​HTML></​p></​HTML><​HTML></​li></​HTML><​HTML></​ul></​HTML>​+
  
 Generatoarele de octeți sunt utile pentru a testa aplicațiile pe care le dezvoltăm. Majoritatea aplicațiilor pe care le vom scrie, ca și cele pe care le utilizăm, citesc și prelucrează informații. Testăm o aplicație pentru că vrem să verificăm că nu avem buguri. Pentru aceasta putem să folosim seturi de date de intrare cât mai variate și mai aleatoare, adică inputuri random. Folosim utilitarul ''​%%dd%%''​ pentru a genera un fișier de 100 MB cu octeți random, ca în exemplul de mai jos: Generatoarele de octeți sunt utile pentru a testa aplicațiile pe care le dezvoltăm. Majoritatea aplicațiilor pe care le vom scrie, ca și cele pe care le utilizăm, citesc și prelucrează informații. Testăm o aplicație pentru că vrem să verificăm că nu avem buguri. Pentru aceasta putem să folosim seturi de date de intrare cât mai variate și mai aleatoare, adică inputuri random. Folosim utilitarul ''​%%dd%%''​ pentru a genera un fișier de 100 MB cu octeți random, ca în exemplul de mai jos:
Line 291: Line 210:
   * ''​%%count%%''​ - block count - numărul de block-uri citite   * ''​%%count%%''​ - block count - numărul de block-uri citite
  
-**Exercițiu**:​ Creați un fișier numit ''​%%rand-250mb%%''​ folosind utilitarul ''​%%dd%%''​.+  * **Exercițiu**:​ Creați un fișier numit ''​%%rand-50mb%%''​ folosind utilitarul ''​%%dd%%''​.
  
 <​note>​ <​note>​
uso/laboratoare/laborator-07/improve-shell.1637016269.txt.gz · Last modified: 2021/11/16 00:44 by mihai_daniel.soare
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