Hur man använder Linux lsof-kommandot

By rik

I Linux-världen betraktas allt som en fil, men det omfattar mer än bara de filer som lagras på din hårddisk. Denna handledning visar hur du kan använda kommandot `lsof` för att utforska alla de olika enheter och processer som behandlas som filer.

Allt är en fil i Linux

Den välkända frasen ”allt i Linux är en fil” är i grunden sann. En fil är i sin kärna en samling av bytes. När dessa bytes läses in i ett program eller skickas till en skrivare, genereras en ström av data. På samma sätt kan de även ta emot en ström av bytes när de skrivs till.

Många andra systemkomponenter, som tangentbord, nätverksanslutningar, skrivare och olika kommunikationsprocesser, hanterar också strömmar av bytes. Eftersom de antingen tar emot, genererar eller både tar emot och genererar dessa bytesströmmar, kan de – på en låg nivå – hanteras som om de vore filer.

Detta designval var en viktig förenkling i implementeringen av Unix-operativsystemet. Det innebar att man kunde skapa en liten uppsättning med verktyg, hanterare och API:er för att interagera med en mängd olika systemresurser.

De data- och programfiler som vi vanligtvis tänker på, och som finns på din hårddisk, är de traditionella filsystemfilerna. Vi kan använda kommandot `ls` för att lista dem och se information om dem.

Men hur kan vi se de processer och enheter som behandlas som filer bakom kulisserna? Det är där kommandot `lsof` kommer in i bilden. Det listar alla öppna filer i systemet, det vill säga, allt som hanteras som om det vore en fil.

Kommandot lsof

Eftersom många av de processer och enheter som `lsof` rapporterar om tillhör `root` (superanvändaren) eller har startats av `root`, behöver du använda `sudo` med kommandot `lsof`.

Denna lista kommer att vara väldigt lång, så vi skickar utdata till kommandot `less` för att kunna navigera i den.

sudo lsof | less

Innan `lsof` visar sin utdata, kan användare av GNOME se en varning i terminalen:

lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
Output information may be incomplete.

`lsof` försöker bearbeta alla monterade filsystem, men här har det stött på ett virtuellt filsystem från GNOME (GVFS). Det är ett speciellt filsystem i användarutrymmet (FUSE) och fungerar som en brygga mellan GNOME, dess API:er och själva kärnan. Endast den användare som monterade filsystemet (i detta fall GNOME) kan komma åt det, inte ens `root`. Du kan lugnt ignorera denna varning.

Utdata från `lsof` innehåller många kolumner, där de vänstra kolumnerna visar:

Och kolumnerna till höger visar:

Förstå kolumnerna i `lsof`

Det är inte alla kolumner som är relevanta för alla typer av öppna filer. Det är normalt att vissa av dem kan vara tomma.

Kommando: Namnet på det kommando som är kopplat till den process som öppnade filen.
PID: Processidentifikationsnummer för processen som öppnade filen.
TID: Trådidentifikationsnummer. En tom kolumn betyder att det inte är en tråd, utan en process.
Användare: Användar-ID eller namnet på den användare som processen tillhör, eller användar-ID:t eller inloggningsnamnet för personen som äger katalogen i `/proc` där `lsof` hämtar information om processen.
FD: Visar filbeskrivningen för filen (se nedan).
Typ: Typen av nod som är associerad med filen (se nedan).
Enhet: Innehåller antingen enhetsnumren, separerade med kommatecken, för en speciell teckenfil, block-specialfil, vanlig fil, katalog eller NFS-fil, eller en kärnreferensadress som identifierar filen. Den kan också visa basadressen eller enhetsnamnet för en Linux AX.25-uttagsenhet.
Storlek/Av: Visar storleken på filen eller filförskjutningen i bytes.
Nod: Visar nodnumret för en lokal fil, inodnumret för en NFS-fil på servern eller en internetprotokolltyp. Den kan visa `STR` för en ström eller IRQ- eller inodnumret för en Linux AX.25-uttagsenhet.
Namn: Visar namnet på monteringspunkten och filsystemet där filen finns.

Kolumnen FD

Filbeskrivningen i kolumnen FD kan ha många alternativ; man-sidan listar alla. En filbeskrivning i FD-kolumnen kan bestå av tre delar: filbeskrivning, lägestecken och låstecken. Några vanliga filbeskrivningar är:

cwd: Aktuell arbetskatalog.
err: Fel i FD-informationen (se kolumnen NAMN).
ltx: Delad bibliotekstext (kod och data).
m86: DOS Merge-mappad fil.
mem: Minnesmappad fil.
mmap: Minnesmappad enhet.
pd: Föräldrakatalog.
rtd: Rotkatalog.
txt: Programtext (kod och data).
Ett tal som representerar en filbeskrivning.

Lägestecknet kan vara något av följande:

r: Läsåtkomst.
w: Skrivåtkomst.
u: Läs- och skrivåtkomst.
’ ’: Ett blanksteg om läget är okänt och det inte finns något låstecken.
–: Läge okänt och det finns ett låstecken.

Låstecknet kan vara något av följande:

r: Läslås på en del av filen.
R: Läslås på hela filen.
w: Skrivlås på en del av filen.
W: Skrivlås på hela filen.
u: Läs- och skrivlås av valfri längd.
U: Okänd låstyp.
’ ’: Ett blanksteg. Inget lås.

Kolumnen TYPE

Det finns över 70 möjliga värden som kan visas i kolumnen TYPE. Några vanliga poster är:

REG: Vanlig filsystemfil.
DIR: Katalog.
FIFO: Först in, först ut.
CHR: Specialfil för tecken.
BLK: Specialfil för block.
INET: Internetuttag.
unix: UNIX-domänsocket.

Visa processer som har öppnat en fil

För att se vilka processer som har öppnat en specifik fil, ange filnamnet som en parameter till `lsof`. Om du till exempel vill se processer som har öppnat filen `kern.log`, använd följande kommando:

sudo lsof /var/log/kern.log

`lsof` visar att det är processen `rsyslogd`, som startades av användaren `syslog`, som har filen öppen.

Visa alla filer som har öppnats från en katalog

För att se alla filer som har öppnats från en specifik katalog, och processerna som öppnade dem, skicka katalogen till `lsof` som en parameter. Du behöver använda alternativet `+D` (katalog).

För att se alla öppna filer i katalogen `/var/log/`, använd följande kommando:

sudo lsof +D /var/log/

`lsof` svarar med en lista över alla öppna filer i den angivna katalogen.

För att se alla filer som öppnats från katalogen `/home`, använd följande kommando:

sudo lsof +D /home

Filerna som har öppnats från `/home`-katalogen visas nu. Notera att listan är smalare här, på grund av kortare beskrivningar i kolumnerna.

Lista filer som har öppnats av en process

För att se filer som har öppnats av en specifik process, använd alternativet `-c` (kommando). Det är möjligt att ange flera sökvärden till `lsof` samtidigt.

sudo lsof -c ssh -c init

Här visas de filer som har öppnats av processerna `ssh` eller `init`.

Visa filer som har öppnats av en specifik användare

För att begränsa listan till filer som har öppnats av en viss användare, använd alternativet `-u` (användare). I det här exemplet letar vi efter filer som har öppnats av processer som ägs av eller körs för användaren Mary.

sudo lsof -u mary

Alla listade filer har öppnats för användaren Mary, inklusive filer som har öppnats av skrivbordsmiljön eller som ett resultat av att Mary har loggat in.

Uteslut filer som har öppnats av en användare

För att utesluta filer som har öppnats av en specifik användare, använd operatorn `^`. Att utesluta användare från listan gör det enklare att hitta den information du letar efter. Du måste använda alternativet `-u` som tidigare och lägga till tecknet `^` i början av användarens namn.

sudo lsof +D /home -u ^mary

Den här gången innehåller listan över filerna i `/home`-katalogen inte några av filerna som öppnats av användaren Mary.

Lista filer som har öppnats av en process

För att lista filerna som har öppnats av en specifik process, använd alternativet `-p` (process) och ange process-ID:t som en parameter.

sudo lsof - p 4610

Här visas alla filer som har öppnats av det process-ID som du angett.

Lista process-ID:n som har öppnat en fil

För att se process-ID:n för de processer som har öppnat en viss fil, använd alternativet `-t` (terse) och ange namnet på filen.

sudo lsof -t /usr/share/mime/mime.cache

Process-ID:n visas i en enkel lista.

Använd OCH- och ELLER-sökningar

Låt oss lista de filer som har öppnats av användaren Mary och som är relaterade till SSH-processer. Vi vet att vi kan ange fler än ett sökobjekt i kommandoraden, så detta borde vara enkelt.

sudo lsof -u mary -c ssh

Men när vi tittar på utdata från `lsof` ser det inte rätt ut. Det finns poster som startades av `root`.

Detta var inte vad vi förväntade oss, vad hände?

När du anger flera sökvärden returnerar `lsof` alla filer som matchar det första sökvärdet *eller* det andra sökvärdet, och så vidare. Med andra ord, det utför en ELLER-sökning.

För att tvinga `lsof` att utföra en OCH-sökning använder du alternativet `-a` (och). Detta innebär att endast de filer som matchar både det första *och* det andra sökvärdet kommer att visas i listan.

Låt oss prova igen och använda alternativet `-a`.

sudo lsof -u mary -c ssh -a

Nu visas endast filer som har öppnats av, eller för, Mary och som är relaterade till SSH-kommandot.

Uppdatera skärmen automatiskt

Vi kan använda alternativet `+|-r` (upprepa) för att sätta `lsof` i upprepningsläge. Upprepningsalternativet kan tillämpas på två sätt, antingen `+r` eller `-r`. Vi måste också ange hur många sekunder som `lsof` ska vänta innan den uppdaterar skärmen.

Med båda formaterna visar `lsof` resultatet, men lägger till en streckad linje längst ner på skärmen. Den väntar sedan det antal sekunder som angetts och uppdaterar sedan skärmen med nya resultat.

Med alternativet `-r` fortsätter detta tills du trycker på Ctrl+C. Med formatet `+r` fortsätter det tills det inte finns fler resultat eller tills du trycker på Ctrl+C.

sudo lsof -u mary -c ssh -a -r5

Notera den streckade linjen längst ner i listan. Den separerar varje ny visning av data när utdata uppdateras.

Visa filer som är kopplade till internetanslutningar

Alternativet `-i` (internet) gör att du kan se filer som har öppnats av processer som är kopplade till nätverks- och internetanslutningar.

lsof -i

Alla filer som har öppnats av nätverks- och internetanslutningar visas.

Visa filer kopplade till internetanslutningar efter process-ID

För att se filer som har öppnats av internetanslutningar kopplade till ett specifikt process-ID, lägg till alternativen `-p` och `-a`.

Här letar vi efter filer som öppnas av en internet- eller nätverksanslutning via en process med ID 606.

sudo lsof -i -a -p 606

Nu visas alla filer som öppnats av process-ID 606 som är kopplade till internet- eller nätverksanslutningar.

Visa filer kopplade till internetanslutningar och kommandon

Vi kan använda alternativet `-c` (kommando) för att söka efter filer som har öppnats av specifika processer. För att leta efter filer som har öppnats via internet- eller nätverksanslutningar som är kopplade till processen `ssh`, använd följande kommando:

lsof -i -a -c ssh

Alla filer som öppnats på grund av `ssh`-processerna listas i utdata.

Visa filer kopplade till internetanslutningar och portar

Vi kan också få `lsof` att rapportera filer som har öppnats via internet- eller nätverksanslutningar på en specifik port. För att göra detta använder vi tecknet `:` följt av portnumret.

Här ber vi `lsof` att lista de filer som har öppnats av nätverks- eller internetanslutningar på port 22.

lsof -i :22

Alla listade filer har öppnats av processer kopplade till port 22 (standardporten för SSH-anslutningar).

Visa filer kopplade till internetanslutningar och protokoll

Vi kan be `lsof` att visa filer som har öppnats av processer kopplade till nätverks- och internetanslutningar som använder ett visst protokoll. Vi kan välja mellan TCP, UDP och SMTP. Låt oss använda TCP-protokollet och se vad vi får.

sudo lsof -i tcp

Endast de filer som har öppnats av processer som använder TCP-protokollet visas.

Vi har bara skrapat på ytan

Detta ger en grundläggande överblick över vanliga användningsfall för `lsof`, men det finns mycket mer att utforska. Mansidan är över 2800 rader lång, vilket visar hur mycket mer det finns att lära.

Kommandot `lsof` kan användas för att utforska de djupaste lagren av öppna filer och pseudofiler. Vi har presenterat en översiktskarta; hela atlasen hittar du i man-sidan.