This shows you the differences between two versions of the page.
uso:laboratoare:ac:laborator-05:inspect-files [2020/11/17 11:28] ioana_maria.culic |
— (current) | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Inspectarea fișierelor ====== | ||
- | ===== Inspectarea rapida a conținutului fișierelor ===== | ||
- | |||
- | În secțiunea anterioară, ''%%improve_cli_inspect_fs%%'', am văzut cum căutăm fișiere în sistem cu ajutorul utilitarului ''%%find%%''. Căutăm un fișier cu un scop: vrem să găsim fișierul ''%%README%%'' pentru informații despre compilarea proiectului, vrem să ne amintim un detaliu de implementare din cod, etc. | ||
- | |||
- | De cele mai multe ori acțiunea noastră se poate grupa în una din următoarele două categorii: | ||
- | |||
- | * Ne dorim să inspectăm rapid conținutul fișierelor pentru a ne da seama dacă am găsit informația căutată. | ||
- | * Ne dorim să afișăm pe ecran conținutul fișierelor pentru a extrage și prelucra informații din acestea. | ||
- | |||
- | ==== Prelucrarea informației dintr-un fișier ==== | ||
- | |||
- | Pentru a afișa pe ecran conținutul unui fișier folosim utlitarul ''%%cat%%''. Rulăm comanda de mai jos, pentru a exemplifica: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ cat workspace/C/searching/binary_search.c | ||
- | /** | ||
- | * @file | ||
- | * @brief Program to perform [binary | ||
- | * search](https://en.wikipedia.org/wiki/Binary_search_algorithm) of a target | ||
- | * value in a given *sorted* array. | ||
- | * @authors [James McDermott](https://github.com/theycallmemac) - recursive | ||
- | * algorithm | ||
- | * @authors [Krishna Vedala](https://github.com/kvedala) - iterative algorithm | ||
- | */ | ||
- | #include <assert.h> | ||
- | #include <stdio.h> | ||
- | |||
- | [...] | ||
- | </code> | ||
- | Observăm că pentru un fișier cu un număr mare de linii, așa cum este **binary_search.c**, afișarea întregului conținut pe ecran devine un impediment în a putea înțelege și urmări conținutul. De aceea vă încurajăm să folosiți ''%%less%%'' în loc de ''%%cat%%'' pentru a inspecta un fișier: vă este mult mai ușor să vă plimbați în interiorul fișierului și puteți folosi funcția search pentru a căuta în fișier. De asemeni, folosind ''%%less%%'' vă păstrați consola curată și puteți urmări mai ușor ce comenzi ați dat anterior și care au fost rezultatele acestora. | ||
- | |||
- | Folosim comanda ''%%cat%%'' în combinație cu alte comenzi pentru a extrage sau filtra conținutul anumitor fișiere. Comanda ''%%cat%%'' primește ca argumente calea către unul sau mai multe fișiere și afișează pe ecran conținutul concatenat al acestora. | ||
- | |||
- | Un exemplu uzual este faptul că vrem să extragem informațiile despre starea memoriei sistemului din fișierul ''%%/proc/meminfo%%''. Pentru aceasta rulăm comanda de mai jos: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ cat /proc/meminfo | grep "Mem" | ||
- | MemTotal: 2041248 kB | ||
- | MemFree: 236092 kB | ||
- | MemAvailable: 874420 kB | ||
- | </code> | ||
- | În exemplul de mai sus folosim ''%%cat%%'' pentru a oferi ca intrare conținutul fișierului ''%%/proc/meminfo%%'' utilitarului ''%%grep%%''; cu utilitarul ''%%grep%%'' filtrăm conținutul după textul ''%%"Mem"%%''. Cu alte cuvinte, outputul comenzii ''%%cat /proc/meminfo%%'', adică conținutul fișierului ''%%/proc/meminfo%%'' este textul pe care utilitarul ''%%grep%%'' îl prelucrează. | ||
- | |||
- | **Exercițiu**: Plecând de la exemplul de mai sus, extrageți din fișierul ''%%/proc/cpuinfo%%'' dimensiunea memoriei cache a procesorului vostru; filtrați conținutul după textul ''%%"cache"%%''. | ||
- | |||
- | === Afișarea parțială a unui fișier === | ||
- | |||
- | Am văzut că utilitarul ''%%cat%%'' afișează întreg conținutul unui fișier. Există scenarii în care suntem interesați doar de începutul sau sfârșitul unui conținut. Pentru aceste cazuri putem folosi utilitarele: | ||
- | |||
- | * ''%%head%%'' - afișează primele **10** linii din conținut | ||
- | * ''%%tail%%'' - afișează ultimele **10** linii din conținut | ||
- | |||
- | <note> | ||
- | |||
- | |||
- | Valoarea **10** este valoarea implicită a ambelor utilitare, dar putem specifica un alt număr de linii. | ||
- | </note> | ||
- | |||
- | Așa cum am observat în capitolul despre procese, putem folosi utilitarul ''%%ps%%'' pentru a vedea care sunt procesele din sistem și ce resurse consumă acestea. Memoria sistemului este una dintre cele mai importante resurse; dacă sistemul nostru rămâne fără memorie disponibilă, tot sistemul este afectat: sistemul se va "mișca" mai greu, procesele se vor "mișca" mai greu sau pot chiar să își întrerupă activitatea. Știind acest lucru, suntem interesați să vedem care sunt primele zece procese care consumă cea mai multă memorie. | ||
- | |||
- | Folosim utilitarul ''%%ps%%'' pentru a afișa toate procesele din sistem: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ ps -e -ouser,uid,pid,%mem,%cpu,rss,cmd --sort=%mem | ||
- | |||
- | USER UID PID %MEM %CPU RSS CMD | ||
- | root 0 2 0.0 0.0 0 [kthreadd] | ||
- | |||
- | [...] | ||
- | |||
- | 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 | ||
- | student 1000 8307 3.1 0.0 64628 /usr/lib/evolution/evolution-calendar-factory | ||
- | root 0 1338 3.8 0.0 78880 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock | ||
- | 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 | ||
- | student 1000 8437 8.4 0.0 171916 /usr/bin/gnome-software --gapplication-service | ||
- | student 1000 7938 18.0 0.1 368304 /usr/bin/gnome-shell | ||
- | </code> | ||
- | Am folosit opțiunea ''%%-ouser,uid,pid,%mem,%cpu,rss,cmd%%'' pentru a selecta coloanele pe care să le afișeze ''%%ps%%''. | ||
- | |||
- | Am folosit opțiunea ''%%--sort%%'' cu argumentul ''%%%mem%%'' pentru a sorta procesele după procentul de memorie folosită. | ||
- | |||
- | <note> | ||
- | |||
- | |||
- | Folosiți comanda ''%%ps -e -ouser,uid,pid,%mem,%cpu,rss,cmd --sort=%mem | less%%'' pentru a vizualiza rezultatul comenzii ''%%ps%%'' într-o sesiune interactivă ''%%less%%''. | ||
- | </note> | ||
- | |||
- | Observăm că avem procesele sortate crescător după coloana ''%%%MEM%%''. Folosim utilitarul ''%%tail%%'' pentru a extrage din rezultatul ''%%ps%%'' cele mai consumatoare zece procese: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ ps -e -ouser,uid,pid,%mem,%cpu,rss,cmd --sort=%mem | tail | ||
- | student 1000 12966 1.8 0.0 38216 /usr/lib/gnome-terminal/gnome-terminal-server | ||
- | root 0 1074 2.2 0.0 45460 /usr/bin/containerd | ||
- | student 1000 8274 2.3 0.0 48296 nautilus-desktop | ||
- | root 0 336 2.6 0.0 53612 /lib/systemd/systemd-journald | ||
- | 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 | ||
- | student 1000 8307 3.1 0.0 64628 /usr/lib/evolution/evolution-calendar-factory | ||
- | root 0 1338 3.8 0.0 78880 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock | ||
- | 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 | ||
- | student 1000 8437 8.4 0.0 171916 /usr/bin/gnome-software --gapplication-service | ||
- | student 1000 7938 18.0 0.1 368248 /usr/bin/gnome-shell | ||
- | </code> | ||
- | În acest moment am găsit răspunsul căutat, dar avem două mici neajunsuri: | ||
- | |||
- | * Ne lipsește antetul, așa că nu știm ce informații avem pe coloane | ||
- | * Procesele sunt sortate crescător, a.î. cel mai consumator este ultimul; vrem să fie sortate descrescător | ||
- | |||
- | Rezolvăm cele două probleme prin intermediul opțiunii ''%%--sort%%'': dacă punem un ''%%-%%'' (minus) în fața argumentului după care sortăm, o să sortăm descrescător. Rulăm comanda: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ ps -e -ouser,uid,pid,%mem,%cpu,rss,cmd --sort=-%mem | less | ||
- | USER UID PID %MEM %CPU RSS CMD | ||
- | student 1000 7938 18.0 0.1 368248 /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 | ||
- | |||
- | [...] | ||
- | </code> | ||
- | Observăm că acum avem formatul dorit. Ne mai rămâne să extragem primele **11** linii din rezultatul comenzii de mai sus; **11** deoarece prima este linia antetului iar următoarele zece sunt procesele de interes. Pentru aceasta utilizăm comanda ''%%head%%'' cu opțiunea ''%%-11%%'' ca în 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 | ||
- | </code> | ||
- | |||
- | ===== Căutarea în fișiere ===== | ||
- | |||
- | Așa cum am văzut până în acest punct din carte, majoritatea comenzilor Linux afișează o gamă largă de informații pe care apoi utilizatorul (adică noi) le filtrează pentru a extrage ceea ce îl intresează. La începutul acestei secțiuni, dar și de-a lungul cărții, am folosit utilitarul ''%%grep%%'' ca să filtrăm rezultatul unei comenzi. | ||
- | |||
- | Comanda ''%%grep%%'' este una dintre cele mai folosite în linie de comandă. Sintaxa de folosire a ''%%grep%%'' este următoarea: | ||
- | |||
- | <code bash> | ||
- | SYNOPSIS | ||
- | grep [OPTIONS] PATTERN [FILE...] | ||
- | </code> | ||
- | ''%%grep%%'' caută **PATTERN** în lista de fișiere primită ca argument și afișează liniile care conțin **PATTERN**-ul căutat. Atunci când nu primește nici un fișier, citește text de la tastatură (intrarea standard) și afișează liniile care conțin **PATTERN**-ul căutat. | ||
- | |||
- | Până acum noi am utilizat ''%%grep%%'' după modelul de mai jos: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ cat workspace/C/searching/binary_search.c | grep search | ||
- | * search](https://en.wikipedia.org/wiki/Binary_search_algorithm) of a target | ||
- | * \param[in] arr array to search | ||
- | * \param l left index of search range | ||
- | * \param r right index of search range | ||
- | * \param x target value to search for | ||
- | int binarysearch1(const int *arr, int l, int r, int x) | ||
- | |||
- | [...] | ||
- | </code> | ||
- | În exemplul de mai sus, operatorul ''%%|%%'' trimite textul afișat de comanda ''%%cat%%'' către intrarea standard a comenzii ''%%grep%%''. Vom discuta mai multe despre acesta în secțiunea ''%%improve_cli_improve_shell_oneliners%%''. | ||
- | |||
- | Comanda următoare este echivalentă cu cea de mai sus: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ grep search workspace/C/searching/binary_search.c | ||
- | * search](https://en.wikipedia.org/wiki/Binary_search_algorithm) of a target | ||
- | * \param[in] arr array to search | ||
- | * \param l left index of search range | ||
- | * \param r right index of search range | ||
- | * \param x target value to search for | ||
- | int binarysearch1(const int *arr, int l, int r, int x) | ||
- | [...] | ||
- | </code> | ||
- | Observăm modul de folosire: ''%%grep PATTERN cale/către/fișier%%''. | ||
- | |||
- | ==== Exerciții ==== | ||
- | |||
- | - Căutați //patternul// "l" în fișierul ''%%binary_search.c%%'', pentru a vedea unde este folosit parametrul **left**. Observați cât de multe rezultate irelevante ați găsit datorită faptului că am căutat doar caracterul **l**. Aici există o lecție de învățat. Numele variabilelor sunt foarte improtante: nu fac doar codul mai ușor de înțeles, dar ajută și căutarea. Folosiți //patternul// "param l" în încercarea de a restrânge căutarea. |