În universul Linux, unde totul este perceput ca un fișier, realitatea depășește simpla stocare pe disc. Acest ghid își propune să vă introducă în tainele comenzii `lsof`, dezvăluind cum aceasta expune o lume întreagă de dispozitive și procese, toate gestionate ca și cum ar fi fișiere.
În Linux, totul devine fișier
Afirmația frecventă că în Linux totul este un fișier nu este departe de adevăr. Un fișier, în esență, reprezintă o colecție de octeți. Atunci când aceste date sunt accesate de un program sau trimise către o imprimantă, ele se prezintă ca un flux continuu de octeți. Similar, când scriem în fișier, acesta primește un flux de octeți.
Această logică se extinde și la alte elemente ale sistemului, precum tastaturile, conexiunile socket, imprimantele și procesele de comunicare. Fiindcă toate manipulează fluxuri de octeți, acestea pot fi tratate la un nivel fundamental ca fișiere.
Această abordare a designului a simplificat construcția sistemului de operare Unix, necesitând un set minimal de mecanisme, instrumente și API-uri pentru gestionarea unei varietăți impresionante de resurse.
Fișierele de date și programe, găzduite pe unitatea de stocare, sunt fișiere obișnuite din perspectiva sistemului. Comanda `ls` ne permite să le listăm și să obținem informații despre ele.
Dar cum explorăm restul proceselor și dispozitivelor, care sunt tratate tot ca fișiere? Răspunsul este comanda `lsof`. Aceasta afișează lista fișierelor deschise în sistem, adică toate acele elemente gestionate ca și cum ar fi fișiere.
Explorând cu ajutorul comenzii `lsof`
Multe dintre elementele pe care `lsof` le raportează aparțin utilizatorului root sau au fost inițiate de acesta. Prin urmare, este necesară utilizarea comenzii `sudo` împreună cu `lsof`.
Dat fiind că lista poate fi foarte mare, vom utiliza `less` pentru a o parcurge pas cu pas.
sudo lsof | less
Înainte de afișarea rezultatelor `lsof`, utilizatorii GNOME ar putea observa un mesaj de avertizare în terminal.
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs Output information may be incomplete.
`lsof` încearcă să analizeze toate sistemele de fișiere montate. Acest mesaj este generat de întâlnirea cu un sistem de fișiere virtual GNOME (GVFS). Acesta reprezintă un caz special de sistem de fișiere în spațiul utilizatorului (FUSE), acționând ca o interfață între GNOME, API-urile sale și kernel. Accesul la aceste sisteme de fișiere este restricționat, chiar și pentru root, limitat la proprietarul care l-a montat (în acest caz, GNOME). Acest avertisment poate fi ignorat.
Rezultatele oferite de `lsof` sunt detaliate. Coloanele din stânga sunt:
Iar coloanele din dreapta sunt:
Analiza coloanelor `lsof`
Nu toate coloanele sunt relevante pentru fiecare tip de fișier deschis. Unele dintre ele pot apărea goale.
Comanda: Numele comenzii asociate procesului care a deschis fișierul.
PID: Numărul de identificare al procesului care a deschis fișierul.
TID: Numărul de identificare al sarcinii (firului). Un câmp gol semnifică faptul că nu este o sarcină, ci un proces.
Utilizator: Identificatorul sau numele utilizatorului care deține procesul, sau al persoanei care deține directorul din /proc unde `lsof` găsește informații despre proces.
FD: Descriptorul fișierului. Detalii suplimentare despre descriptori sunt oferite mai jos.
Tip: Tipul nodului asociat fișierului. Tipuri specifice sunt descrise mai jos.
Dispozitiv: Conține numerele dispozitivelor, separate prin virgulă, pentru fișiere speciale de tip caracter, bloc, obișnuite, directoare sau NFS. Alternativ, poate conține o adresă de referință a nucleului ce identifică fișierul sau numele dispozitivului unui socket Linux AX.25.
Dimensiune/Deplasare: Dimensiunea fișierului sau decalajul, exprimat în octeți.
Nod: Numărul de nod al unui fișier local sau numărul inod al unui fișier NFS de pe server. Poate indica STR pentru un flux, IRQ-ul sau numărul de inod al unui socket Linux AX.25.
Nume: Numele punctului de montare și al sistemului de fișiere în care se află fișierul.
Coloana FD
Intrarea în coloana FD (descriptorul de fișier) poate avea mai multe valori. Pentru detalii complete, consultați pagina de manual.
Un descriptor de fișier este format din trei elemente: un descriptor, un caracter de mod și un caracter de blocare. Descriptori uzuali includ:
cwd: Directorul de lucru curent.
err: Eroare la nivelul descriptorului FD (consultați coloana NUME).
ltx: Textul bibliotecii partajate (cod și date).
m86: Fișier mapat DOS Merge.
mem: Fișier mapat în memorie.
mmap: Dispozitiv mapat în memorie.
pd: Directorul părinte.
rtd: Directorul rădăcină.
txt: Textul programului (cod și date).
Un număr: Reprezentând un descriptor de fișier.
Caracterul de mod poate fi:
r: Acces de citire.
w: Acces de scriere.
u: Acces de citire și scriere.
‘ ‘: Spațiu, mod necunoscut, fără caracter de blocare.
-: Mod necunoscut, cu caracter de blocare.
Caracterul de blocare poate fi:
r: Blocare de citire pe o parte a fișierului.
R: Blocare de citire pe întregul fișier.
w: Blocare de scriere pe o parte a fișierului.
W: Blocare de scriere pe întregul fișier.
u: Blocare de citire și scriere de orice lungime.
U: Tip de blocare necunoscut.
‘ ‘: Spațiu, fără blocare.
Coloana TIP
Există peste 70 de valori posibile în coloana TIP. Printre valorile frecvente se numără:
REG: Fișier obișnuit al sistemului de fișiere.
DIR: Director.
FIFO: First In First Out.
CHR: Fișier special de tip caracter.
BLK: Fișier special de tip bloc.
INET: Socket de internet.
unix: Socket de domeniu UNIX.
Identificarea proceselor care accesează un fișier
Pentru a vedea procesele care accesează un fișier specific, dați numele fișierului ca parametru lui `lsof`. De exemplu, pentru a identifica procesele care accesează `kern.log`, utilizați:
sudo lsof /var/log/kern.log
`lsof` răspunde indicând procesul `rsyslogd`, inițiat de utilizatorul `syslog`.
Vizualizarea fișierelor deschise dintr-un director
Pentru a vedea fișierele deschise dintr-un director și procesele asociate, specificați directorul ca parametru pentru `lsof`, folosind opțiunea `+D` (director).
Pentru a vedea toate fișierele deschise în `/var/log/`, utilizați:
sudo lsof +D /var/log/
`lsof` oferă o listă cu toate fișierele deschise în acel director.
Pentru a vedea fișierele deschise din directorul `/home`, utilizați:
sudo lsof +D /home
Se afișează fișierele deschise din `/home`. Remarcați că, datorită descrierilor mai scurte în unele coloane, lista este mai compactă.
Listarea fișierelor deschise de un proces
Pentru a vedea fișierele deschise de un proces specific, folosiți opțiunea `-c` (comandă). Puteți furniza mai mulți termeni de căutare către `lsof` simultan.
sudo lsof -c ssh -c init
`lsof` oferă o listă a fișierelor deschise de oricare dintre procesele specificate în linia de comandă.
Vizualizarea fișierelor deschise de un utilizator
Pentru a filtra rezultatele și a afișa doar fișierele deschise de un utilizator specific, utilizați opțiunea `-u` (utilizator). În acest exemplu, vom căuta fișierele deschise de procesele deținute sau lansate în numele utilizatorului Mary.
sudo lsof -u mary
Toate fișierele afișate au fost deschise în numele utilizatorului Mary. Acestea includ fișierele deschise de mediul desktop sau în timpul logării lui Mary.
Excluderea fișierelor deschise de un utilizator
Pentru a exclude fișierele deschise de un utilizator, folosiți operatorul `^`. Excluderea utilizatorilor simplifică identificarea informațiilor de interes. Trebuie să utilizați opțiunea `-u`, adăugând `^` la începutul numelui de utilizator.
sudo lsof +D /home -u ^mary
Acum, lista pentru directorul `/home` nu include fișierele deschise de utilizatorul Mary.
Listarea fișierelor deschise de un anumit proces
Pentru a lista fișierele deschise de un proces, utilizați opțiunea `-p` (proces) și introduceți ID-ul procesului ca parametru.
sudo lsof - p 4610
Sunt listate toate fișierele deschise de procesul cu ID-ul specificat.
Listarea ID-urilor proceselor care accesează un fișier
Pentru a vizualiza ID-urile proceselor care accesează un fișier, utilizați opțiunea `-t` (concis) și specificați numele fișierului.
sudo lsof -t /usr/share/mime/mime.cache
ID-urile proceselor sunt afișate într-o listă simplă.
Utilizarea căutărilor AND și SAU
Să listăm fișierele deschise de utilizatorul Mary, legate de procesele SSH. Știm că putem folosi mai mulți termeni de căutare în linia de comandă, deci ar trebui să fie simplu.
sudo lsof -u mary -c ssh
Să analizăm rezultatul. Nu pare corect; include intrări lansate de root.
Acest lucru nu era așteptat. Ce s-a întâmplat?
Când furnizați mai mulți termeni de căutare, `lsof` returnează orice fișier care se potrivește cu primul termen, sau cu al doilea, și așa mai departe. Adică, efectuează o căutare SAU.
Pentru a efectua o căutare AND, utilizați opțiunea `-a` (și). Astfel, vor fi listate doar fișierele care corespund tuturor termenilor de căutare.
Să încercăm din nou cu opțiunea `-a`.
sudo lsof -u mary -c ssh -a
Acum fiecare fișier din listă a fost deschis de sau în numele lui Mary și este asociat cu comanda SSH.
Reîmprospătarea automată a afișajului
Putem folosi opțiunea `+|-r` (repetare) pentru a activa modul de repetare al lui `lsof`. Aceasta se poate aplica în două moduri: `+r` sau `-r`. De asemenea, trebuie să adăugăm numărul de secunde de așteptare între reîmprospătări.
Cu oricare format, `lsof` afișează rezultatele obișnuit, adăugând o linie întreruptă în josul afișajului. Așteaptă numărul de secunde specificat și actualizează rezultatele.
Cu opțiunea `-r`, repetiția continuă până la apăsarea Ctrl+C. Formatul `+r` repetă afișarea până nu mai există rezultate sau până la Ctrl+C.
sudo lsof -u mary -c ssh -a -r5
Observați linia întreruptă din josul listei. Aceasta separă fiecare afișare actualizată.
Afișarea fișierelor legate de conexiunile la Internet
Opțiunea `-i` (internet) permite vizualizarea fișierelor deschise de procesele asociate cu conexiunile de rețea și internet.
lsof -i
Sunt afișate toate fișierele deschise de conexiunile de rețea și internet.
Afișarea fișierelor legate de conexiunile la Internet prin ID-ul procesului
Pentru a vedea fișierele deschise de conexiunile de internet, asociate cu un ID de proces specific, adăugați opțiunile `-p` și `-a`.
Aici căutăm fișiere deschise printr-o conexiune de internet sau rețea, printr-un proces cu ID-ul 606.
sudo lsof -i -a -p 606
Sunt afișate toate fișierele deschise prin ID-ul procesului 606, asociate cu conexiuni de rețea sau internet.
Afișarea fișierelor asociate cu conexiuni și comenzi la Internet
Putem utiliza opțiunea `-c` (comandă) pentru a căuta fișiere deschise de procese specifice. Pentru a căuta fișiere deschise de conexiuni de internet sau rețea asociate cu procesul ssh, folosim:
lsof -i -a -c ssh
Toate fișierele deschise de procesele ssh sunt afișate în rezultat.
Afișarea fișierelor asociate conexiunilor și porturilor la internet
Putem genera un raport `lsof` cu fișierele deschise prin conexiuni de rețea sau internet pe un port specific. Pentru a face acest lucru, folosim caracterul `:` urmat de numărul portului.
Aici, solicităm lui `lsof` să listeze fișierele deschise de conexiunile de rețea sau internet prin portul 22.
lsof -i :22
Toate fișierele listate au fost deschise de procesele asociate cu portul 22 (portul implicit pentru conexiuni SSH).
Afișarea fișierelor asociate conexiunilor și protocoalelor la Internet
Putem solicita `lsof` să afișeze fișierele deschise de procese asociate cu conexiunile de rețea și internet, care utilizează un anumit protocol. Opțiunile sunt TCP, UDP și SMTP. Să folosim protocolul TCP și să vedem rezultatul.
sudo lsof -i tcp
Singurele fișiere afișate sunt cele deschise de procesele care utilizează protocolul TCP.
O introducere sumară
Acest ghid oferă o bază solidă pentru unele dintre cele mai comune utilizări ale comenzii `lsof`, însă potențialul său este mult mai mare. Complexitatea sa este reflectată de cele peste 2.800 de linii ale paginii de manual.
Comanda `lsof` oferă posibilitatea de a explora în profunzime straturile de fișiere deschise și pseudo-fișiere. Am prezentat o hartă succintă; atlasul detaliat se află în pagina de manual.