This shows you the differences between two versions of the page.
uso:laboratoare:laborator-05:improve-shell [2020/11/10 21:33] liza_elena.babu [Redirectări] |
— (current) | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== O înțelegere mai bună a shellului ====== | ||
- | |||
- | ===== Execuția comenzilor ===== | ||
- | |||
- | ==== Încheierea execuției unei comenzi ==== | ||
- | |||
- | Atunci când rulăm o comandă aceasta își poate încheia execuția în două moduri: cu **succes** sau cu **eșec**. Atunci când își încheie execuția, orice proces întoarce un cod de eroare, care este un număr: | ||
- | |||
- | * Dacă numărul întors are valoarea ''%%0%%'', procesul și-a încheiat execuția cu succes. | ||
- | * Dacă numărul întors are orice altă valoare, procesul și-a încheiat execuția cu eroare, iar codul întors poate fi folosit pentru a afla mai multe informații despre eroarea pe care a întors-o procesul. În pagina ''%%man%%'' a utilitarului ''%%ls%%'' este specificat:<code bash> | ||
- | Exit status: | ||
- | 0 if OK, | ||
- | |||
- | 1 if minor problems (e.g., cannot access subdirectory), | ||
- | |||
- | 2 if serious trouble (e.g., cannot access command-line argument). | ||
- | </code> | ||
- | |||
- | Pentru a vedea codul cu care și-a încheiat execuția o comandă folosim sintaxa ''%%$?%%''. Urmărim exemplul de mai jos: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ ls Desktop/ | ||
- | todos.txt | ||
- | student@uso:~$ echo $? | ||
- | 0 | ||
- | student@uso:~$ ls non-existent | ||
- | ls: cannot access 'non-existent': No such file or directory | ||
- | student@uso:~$ echo $? | ||
- | 2 | ||
- | </code> | ||
- | Observăm că în cazul fișierului inexistet, comanda ''%%ls non-existent%%'' a întors valoarea ''%%2%%'', așa cum era specificat și în pagina de manual. | ||
- | |||
- | === Înlănțuirea comenzilor în funcție de succes sau eșec === | ||
- | |||
- | De multe ori vrem să executăm o succesiune de comenzi pentru a realiza o sarcină. De exemplu, atunci când vrem să instalăm o aplicație o rulăm trei comenzi: | ||
- | |||
- | * O să actualizăm indexul surselor de pachete folosind ''%%apt update%%'' | ||
- | * O să instalăm pachetul care conține aplicația folosind ''%%apt install%%'' | ||
- | * O să rulăm aplicația pentru a valida că instalarea a fost cu succes. | ||
- | |||
- | Preferăm să înlănțuim cele trei comenzi într-una singură pentru că astfel putem să pornim tot acest proces, să plecăm de la calculator, iar când ne întoarcem avem tot sistemul pregătit. | ||
- | |||
- | Pentru a înlănțui comenzi în terminalul bash avem trei operatori disponibili: | ||
- | |||
- | <HTML><ul></HTML> | ||
- | <HTML><li></HTML><HTML><p></HTML>Operatorul ''%%;%%'' - este folosit pentru separarea comenzilor Urmăm exemplul de mai jos:<HTML></p></HTML> | ||
- | <code bash> | ||
- | student@uso:~$ mkdir demo; cd demo; touch Hello; ls | ||
- | Hello | ||
- | </code> | ||
- | <HTML><p></HTML>Î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 ''%%;%%''.<HTML></p></HTML> | ||
- | <HTML><p></HTML>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:<HTML></p></HTML> | ||
- | <code bash> | ||
- | student@uso:~$ mkdir operators/demo; cd operators/demo | ||
- | mkdir: cannot create directory ‘operators/demo’: No such file or directory | ||
- | -bash: cd: operators/demo: No such file or directory | ||
- | </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>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> | ||
- | <code bash> | ||
- | student@uso:~$ mkdir operators/demo && cd operators/demo | ||
- | mkdir: cannot create directory ‘operators/demo’: No such file or directory | ||
- | </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><li></HTML><HTML><p></HTML>Operatorul binar ''%%||%%'' (sau logic) - execută a doua comandă doar dacă prima s-a terminat cu eșec. Urmărim exemplul de mai jos:<HTML></p></HTML> | ||
- | <code bash> | ||
- | student@uso:~$ (ls -d operators || mkdir operators) && ls -d operators | ||
- | ls: cannot access 'operators': No such file or directory | ||
- | operators | ||
- | student@uso:~$ (ls -d operators || mkdir operators) && ls -d operators | ||
- | operators | ||
- | operators | ||
- | </code> | ||
- | <HTML><p></HTML>În exemplul de mai sus, prima comandă ''%%ls%%'' a eșuat, așa că a fost executată comanda ''%%mkdir%%'' și apoi a fost executată ultima comandă ''%%ls%%''. La cea de-a doua rulare, a fost executată cu succes prima comandă ''%%ls%%'', așa că comanda ''%%mkdir%%'' nu a mai fost executată, și apoi a fost executată ultima comandă ''%%ls%%''.<HTML></p></HTML><HTML></li></HTML><HTML></ul></HTML> | ||
- | |||
- | Pentru a rezolva scenariul de la care am plecat inițial, putem rula: | ||
- | |||
- | <code bash> | ||
- | sudo apt update && sudo apt install -y cowsay && cowsay "Howdy" | ||
- | </code> | ||
- | Comanda de mai sus va actualiza indexul pachetelor sursă, va instala pachetul ''%%cowsay%%'' și va rula comanda ''%%cowsay%%'' pentru a valida instalarea. O astfel de înlănțuire de comenzi este numită **oneliner**. | ||
- | |||
- | === Exerciții === | ||
- | |||
- | - Scrieți un oneliner cu ajutorul căruia creați directorul ''%%~/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%%''. | ||
- | |||
- | ==== Înlănțuirea comenzilor folosind operatorul | (pipe) ==== | ||
- | |||
- | Așa cum am descoperit în secțiunile și capitolele anterioare, în mediul Linux avem multe utilitare care rezolvă o nevoie specifică: ''%%ls%%'' afișează informații despre fișiere, ''%%ps%%'' despre procese, ''%%grep%%'' filtrează, etc. Toate acestea au la bază filozofia mediului Linux: "do one thing and do it well". Ca întodeauna, frumusețea stă în simplitate: avem o suită de unelte la dispoziție, fiecare capabilă să rezolve rapid o sarcină dată; pentru a rezolva o problemă mai complexă trebuie doar să îmbinăm uneltele. | ||
- | |||
- | Operatorul ''%%|%%'' (pipe) ne ajută să facem acest lucru. Atunci când folosim operatorul ''%%|%%'' preluăm rezultatul comenzii din stânga operatorului și îl oferim ca intrare comenzii aflate în dreapta operatorului. | ||
- | |||
- | Am folosit de mai multe ori operatorul ''%%|%%'' până acum: | ||
- | |||
- | * Am afișat informații despre procesele din sistem și am filtrat după numele unui proces:<code bash> | ||
- | student@uso:~$ ps -e | grep firefox | ||
- | 14912 pts/0 00:00:19 firefox | ||
- | </code> | ||
- | * Am extras primele zece procese care consumă cel mai mare procent de memorie:<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 | ||
- | </code> | ||
- | |||
- | Până acum am efectuat procesări text pe rezultatul unor comenzi. Folosind operatorul ''%%|%%'' și utilitarul ''%%xargs%%'' putem să folosim rezultatul pe post de argument pentru altă comandă, ca în exemplul de mai jos: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ find . -maxdepth 1 -type f | xargs ls -l | ||
- | -rw------- 1 student student 10992 nov 6 14:56 ./.ICEauthority | ||
- | -rw-r--r-- 1 student student 297 nov 7 00:18 ./.bash_aliases | ||
- | -rw------- 1 student student 43604 nov 5 02:34 ./.bash_history | ||
- | -rw-r--r-- 1 student student 220 aug 6 2018 ./.bash_logout | ||
- | -rw-r--r-- 1 student student 3824 aug 13 19:04 ./.bashrc | ||
- | -rw-r--r-- 1 student student 3159 aug 20 2018 ./.emacs | ||
- | -rw-r--r-- 1 student student 87 aug 21 2018 ./.gitconfig | ||
- | -rw------- 1 student student 361 nov 7 02:40 ./.lesshst | ||
- | </code> | ||
- | Comanda din exemplul de mai sus afișează informații în format lung despre toate fișierele din directorul curent, excluzând directoarele. | ||
- | |||
- | Dacă folosim opțiunea ''%%-p%%'' a utilitarului ''%%xargs%%'', acesta o să ne afișeze ce comandă urmează să execute și așteaptă confirmarea noastră prin apăsarea tastei ''%%y%%'' (yes) sau ''%%n%%'' (no). Este recomandat să folosiți opțiunea ''%%-p%%'' atunci când vă scrieți onelinerul pentru a verifica că comanda pe care urmează să o executați este corectă. În exemplul următor ne dorim să mutăm toate arhivele ''%%.tar%%'' în directorul ''%%archives%%'': | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ ls *.tar | xargs -p mv archives | ||
- | mv archives courses.tar labhidden.tar uso.tar wiki.tar ?...n | ||
- | </code> | ||
- | Cu ajutorul opțiunii ''%%-p%%'' am putut să observăm că comanda nu are sintaxa dorită și am anulat execuția ei. Problema este că avem destinația (''%%archives%%'') înaintea arhivelor care trebuie mutate. | ||
- | |||
- | Pentru a rezolva această problemă folosim opțiunea ''%%-I str%%'', ca mai jos: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ ls *.tar | xargs -I str -p mv str archives | ||
- | mv courses.tar archives ?...n | ||
- | mv labhidden.tar archives ?...n | ||
- | mv uso.tar archives ?...n | ||
- | mv wiki.tar archives ?...n | ||
- | </code> | ||
- | Opțiunea ''%%-I%%'' va înlocui șirul de caractere ''%%str%%'' cu numele arhivelor primite din pipe, așa cum observăm mai sus. Șirul de caractere placeholder poate să fie orice, nu neapărat ''%%str%%''; comanda ''%%ls *.tar | xargs -I {} -p mv {} archives%%'' produce aceelași rezultat. | ||
- | |||
- | ==== 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. | ||
- | |||
- | Orice proces folosește implicit trei fluxuri (streams) de date: | ||
- | |||
- | * **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. | ||
- | |||
- | === Redirectarea erorilor la ieșirea standard === | ||
- | |||
- | Motivul pentru care redirectăm erorile într-un fișier este pentru că vrem să analizăm mesajele de eroare. Avem și scenarii în care rulăm un program care afișează mesaje, la STDOUT și STDERR, de care nu suntem interesați. | ||
- | |||
- | Un astfel de scenariu întâlnim atunci când pornim browserul ''%%firefox%%'' în linia de comandă: acesta afișează din când în când mesaje de care nu suntem interesați. Ne dorim să pornim procesul ''%%firefox%%'' în background și să redirectăm STDOUT și STDERR a.î. să nu ne polueze inutil consola. Urmăm exemplul de mai jos: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ firefox &> firefox-ignore & | ||
- | [1] 10349 | ||
- | student@uso:~$ firefox > firefox-ignore 2>&1 & | ||
- | [2] 10595 | ||
- | </code> | ||
- | Cele două comenzi de mai sus produc aceelași efect: redirectează atât STDOUT, cât și STDERR în fișierul **firefox-ignore**. Efectul este produs prin două metode diferite: | ||
- | |||
- | * Sintaxa ''%%&> cale/către/nume-fișier%%'' - operatorul ''%%&>%%'' va unifica fluxul STDERR cu STDOUT și va redirecta către fișierul primit ca argument. | ||
- | * Sintaxa ''%%> cale/către/nume-fișier 2>&1%%'' - operatorul ''%%2>&1%%'' folosește descriptori de fișier și redirectează STDERR (descriptorul 2) în STDOUT (descriptorul 1). Această sintaxă trebuie precedată de ''%%> cale/către/nume-fișier%%'', pe care o citim: ceea ce se găsește pe fluxul de ieșire STDOUT va fi scris în fișierul **cale/către/nume-fișier**. | ||
- | |||
- | === Fișiere speciale === | ||
- | |||
- | Pe sistemele Linux găsim un număr de fișiere speciale pe care le putem folosim în diferite scopuri: | ||
- | |||
- | <HTML><ul></HTML> | ||
- | <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> | ||
- | student@uso:~$ firefox &> /dev/null & | ||
- | [1] 10349 | ||
- | student@uso:~$ firefox > /dev/null 2>&1 & | ||
- | [2] 10595 | ||
- | </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> | ||
- | <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> | ||
- | <code bash> | ||
- | student@uso:~$ cat /dev/zero | xxd | ||
- | 00000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................ | ||
- | 00000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................ | ||
- | 00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................ | ||
- | 00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................ | ||
- | 00000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................ | ||
- | 00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................ | ||
- | 00000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................ | ||
- | 00000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................ | ||
- | 00000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................ | ||
- | [...] | ||
- | ^C | ||
- | </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> | ||
- | <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> | ||
- | <HTML><blockquote> | ||
- | <HTML><ul></HTML> | ||
- | <HTML><li></HTML>Fișierul ''%%/dev/urandom%%'' este un alt generator de octeți.<HTML></li></HTML><HTML></ul></HTML> | ||
- | </blockquote></HTML> | ||
- | <HTML><p></HTML>Acesta generează atâția octeți cu valoare random cât îi sunt ceruți.<HTML></p></HTML> | ||
- | <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: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ dd if=/dev/urandom of=rand-100mb count=100 bs=1M | ||
- | 100+0 records in | ||
- | 100+0 records out | ||
- | 104857600 bytes (105 MB, 100 MiB) copied, 1,11416 s, 94,1 MB/s | ||
- | student@uso:~$ ls -lh rand-100mb | ||
- | -rw-rw-r-- 1 student student 100M nov 8 17:49 rand-100mb | ||
- | </code> | ||
- | Am folosit următoarele opțiuni ale utilitarului ''%%dd%%'': | ||
- | |||
- | * ''%%if%%'' - input file - calea către fișierul de unde citim | ||
- | * ''%%of%%'' - output file - calea către fișierul unde scriem | ||
- | * ''%%bs%%'' - block size - dimensiunea unui block citit din **if** | ||
- | * ''%%count%%'' - block count - numărul de block-uri citite | ||
- | |||
- | **Exercițiu**: Creați un fișier numit ''%%rand-250mb%%'' folosind utilitarul ''%%dd%%''. | ||
- | |||
- | <note> | ||
- | |||
- | |||
- | Un caz uzual de utilizare a ''%%dd%%'' este suprascrierea unui disc cu informații aleatoare. Această metodă este utilizată ca o formă de securitate atunci când vrem să ștergem informații de pe un disc. Astfel suprascriem datele șterse pentru a preveni posibilitatea recuperării datelor de pe disc. Mai multe informații găsiți [[https://uwnthesis.wordpress.com/2014/07/26/kali-how-to-use-dd-to-wipe-your-usb-pen-the-visual-guide/|aici]]. | ||
- | </note> | ||
- | |||
- | === Exerciții === | ||
- | |||
- | - Afișați primele zece procese sortate în funcție de memoria ocupată (Hint: RSS). Nu uitați să includeți antetul. Redirectați rezultatul în fișierul **top10-rss-consumers**. Modificați comanda astfel încât rezultatul redirectării să nu șteargă conținutul existent. | ||
- | - Afișați ultimele zece procese sortate în funcție de utilizarea procesorului (Hint: CPU). Nu uitați să includeți antetul. Redirectați rezultatul în fișierul **top10-cpu-consumers**. Modificați comanda astfel încât rezultatul redirectării să nu șteargă conținutul existent. | ||
- | |||
- | **Note de subsol** | ||