So verwenden Sie den Linux-Befehl lsof

In der Welt von Linux wird oft behauptet, dass alles eine Datei ist. Doch was bedeutet das wirklich, und wie können wir diese Aussage im Detail betrachten? Dieses Tutorial zeigt Ihnen, wie Sie mit dem Befehl lsof nicht nur herkömmliche Dateien auf Ihrer Festplatte, sondern auch andere Geräte und laufende Prozesse, die als Dateien behandelt werden, inspizieren können.

Die Philosophie „Alles ist eine Datei“ unter Linux

Der oft gehörte Satz, dass unter Linux „alles eine Datei“ sei, trifft im Grunde zu. Eine Datei besteht aus einer Sammlung von Bytes. Programme lesen diese Bytes ein oder senden sie an Drucker, wodurch ein Datenstrom entsteht. Umgekehrt können diese „Dateien“ einen Strom von Bytes akzeptieren, wenn etwas geschrieben wird.

Zahlreiche andere Systemkomponenten, wie Tastaturen, Netzwerkverbindungen, Drucker oder Kommunikationsprozesse, sind ebenso in der Lage, solche Byte-Ströme zu empfangen oder zu erzeugen. Auf einer sehr niedrigen Ebene können diese Geräte daher als Dateien behandelt werden, da sie entweder einen Bytestrom generieren, entgegennehmen oder beides tun.

Diese Designphilosophie trug maßgeblich zur Simplifizierung der Implementierung des Unix-Betriebssystems bei. Sie ermöglichte die Entwicklung eines kleinen Satzes von Handlern, Tools und Schnittstellen (APIs), die eine Vielzahl verschiedenartiger Ressourcen bearbeiten konnten.

Die Daten- und Programmdateien, die sich auf Ihrer Festplatte befinden, sind simple Dateisystemdateien, die wir mit dem Befehl ls anzeigen und Details darüber erfahren können.

Wie können wir aber nun diese anderen Prozesse und Geräte, die wie Dateien behandelt werden, sichtbar machen? Hier kommt der Befehl lsof ins Spiel. Dieser listet alle im System geöffneten Dateien auf, also alles, was wie eine Datei behandelt wird.

Der Befehl `lsof` im Detail

Viele der Prozesse oder Geräte, über die lsof Auskunft gibt, gehören zu root oder wurden von root gestartet. Daher benötigen Sie den Befehl sudo, um lsof auszuführen.

Da die Ausgabe von lsof sehr umfangreich sein kann, leiten wir sie zur besseren Übersicht durch less.

sudo lsof | less

Bevor die eigentliche lsof-Ausgabe erscheint, kann es vorkommen, dass Benutzer von GNOME eine Warnmeldung im Terminal sehen:

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

Diese Meldung erscheint, weil lsof versucht, alle gemounteten Dateisysteme zu analysieren. Die Warnung bezieht sich auf ein virtuelles GNOME-Dateisystem (GVFS), eine spezielle Art von Dateisystem im Benutzerbereich (FUSE). Dieses fungiert als Schnittstelle zwischen GNOME, seinen APIs und dem Kernel. Nur der Besitzer, in diesem Fall GNOME, hat Zugriff darauf, nicht einmal der Benutzer „root“. Sie können diese Warnmeldung getrost ignorieren.

Die Ausgabe von lsof ist sehr detailliert. Die Spalten auf der linken Seite enthalten die folgenden Informationen:

Die Spalten auf der rechten Seite geben folgende Details an:

Die Bedeutung der einzelnen `lsof`-Spalten

Es ist wichtig zu wissen, dass nicht jede Spalte für jeden Dateityp relevant ist. Es ist daher üblich, dass einige Spalten leer bleiben.

COMMAND: Der Name des Befehls, der zu dem Prozess gehört, der die Datei geöffnet hat.
PID: Die Prozess-Identifikationsnummer des Prozesses, der die Datei geöffnet hat.
TID: Die Task- oder Thread-Identifikationsnummer. Eine leere Spalte bedeutet, dass es sich um einen Prozess und nicht um einen Thread handelt.
USER: Die Benutzer-ID oder der Name des Benutzers, zu dem der Prozess gehört, oder die Benutzer-ID oder der Login desjenigen, der das Verzeichnis in /proc besitzt, in dem lsof Informationen über den Prozess findet.
FD: Der Dateideskriptor der Datei. Dateideskriptoren werden weiter unten erläutert.
TYPE: Der Typ des mit der Datei verknüpften Knotens. Die verschiedenen Typen werden im Folgenden beschrieben.
DEVICE: Entweder die durch Kommas getrennten Gerätenummern für eine spezielle Zeichen-, Block-, reguläre, Verzeichnis- oder NFS-Datei oder eine Kernel-Referenzadresse, die die Datei identifiziert. Kann auch die Basisadresse oder den Gerätenamen eines Linux-AX.25-Socket-Geräts anzeigen.
SIZE/OFF: Die Größe der Datei oder der Datei-Offset in Bytes.
NODE: Die Knotennummer einer lokalen Datei oder die Inode-Nummer einer NFS-Datei auf dem Server-Host oder der Internetprotokolltyp. Kann auch STR für einen Stream oder die IRQ- oder Inode-Nummer eines Linux-AX.25-Socket-Geräts anzeigen.
NAME: Der Name des Mount-Points und des Dateisystems, in dem sich die Datei befindet.

Die FD-Spalte genauer betrachtet

Der Dateideskriptor in der Spalte FD kann verschiedene Werte annehmen. Eine vollständige Übersicht bietet die Manpage von lsof.

Der Eintrag in der FD-Spalte kann aus drei Teilen bestehen: einem Dateideskriptor, einem Moduszeichen und einem Sperrzeichen. Hier sind einige gängige Dateideskriptoren:

cwd: Aktuelles Arbeitsverzeichnis.
err: FD-Informationsfehler (siehe Spalte NAME).
ltx: Gemeinsam genutzter Bibliothekstext (Code und Daten).
m86: DOS-Merge-zugeordnete Datei.
mem: Speicherabgebildete Datei.
mmap: Speicherzugeordnetes Gerät.
pd: Übergeordnetes Verzeichnis.
rtd: Root-Verzeichnis.
txt: Programmtext (Code und Daten).
Eine Zahl, die einen Dateideskriptor darstellt.

Das Moduszeichen kann folgende Werte annehmen:

r: Lesezugriff.
w: Schreibzugriff.
u: Lese- und Schreibzugriff.
‚ ‚: Ein Leerzeichen, wenn der Modus unbekannt ist und kein Sperrzeichen vorhanden ist.
–: Modus unbekannt und ein Sperrzeichen ist vorhanden.

Das Sperrzeichen kann eines der folgenden sein:

r: Lesesperre für einen Teil der Datei.
R: Lesesperre für die gesamte Datei.
w: Schreibsperre für einen Teil der Datei.
W: Schreibsperre für die gesamte Datei.
u: Lese- und Schreibsperre beliebiger Länge.
U: Unbekannter Sperrtyp.
‚ ‚: Ein Leerzeichen. Keine Sperre.

Die Spalte TYPE

Es gibt über 70 verschiedene Einträge, die in der TYPE-Spalte erscheinen können. Einige häufige Einträge sind:

REG: Reguläre Dateisystemdatei.
DIR: Verzeichnis.
FIFO: First In First Out (FIFO-Pipe).
CHR: Spezielle Zeichendatei.
BLK: Block-Sonderdatei.
INET: Internet-Socket.
unix: UNIX-Domain-Socket.

Prozesse anzeigen, die eine bestimmte Datei geöffnet haben

Um die Prozesse zu identifizieren, die eine bestimmte Datei geöffnet haben, geben Sie den Dateinamen als Parameter an lsof. Um beispielsweise die Prozesse anzuzeigen, die die Datei kern.log geöffnet haben, verwenden Sie folgenden Befehl:

sudo lsof /var/log/kern.log

lsof zeigt den Prozess rsyslogd an, der vom Benutzer syslog gestartet wurde.

Alle Dateien anzeigen, die aus einem Verzeichnis geöffnet wurden

Um alle Dateien zu sehen, die aus einem bestimmten Verzeichnis geöffnet wurden, und die zugehörigen Prozesse, übergeben Sie das Verzeichnis als Parameter an lsof. Verwenden Sie hierfür die Option +D (Verzeichnis).

Um beispielsweise alle Dateien anzuzeigen, die im Verzeichnis /var/log/ geöffnet sind, nutzen Sie diesen Befehl:

sudo lsof +D /var/log/

lsof listet alle geöffneten Dateien in diesem Verzeichnis auf.

Um alle Dateien anzuzeigen, die aus dem /home-Verzeichnis geöffnet wurden, verwenden Sie diesen Befehl:

sudo lsof +D /home

Die Dateien, die aus dem /home-Verzeichnis geöffnet wurden, werden angezeigt. Beachten Sie, dass bei kürzeren Beschreibungen in einigen Spalten die gesamte Auflistung kompakter ist.

Von einem Prozess geöffnete Dateien anzeigen

Um die Dateien zu identifizieren, die von einem bestimmten Prozess geöffnet wurden, nutzen Sie die Option -c (Befehl). Sie können lsof mehrere Suchbegriffe gleichzeitig übergeben.

sudo lsof -c ssh -c init

lsof listet die Dateien auf, die von einem der in der Befehlszeile genannten Prozesse geöffnet wurden.

Von einem Benutzer geöffnete Dateien anzeigen

Um die Anzeige auf die Dateien zu beschränken, die von einem bestimmten Benutzer geöffnet wurden, verwenden Sie die Option -u (Benutzer). In diesem Beispiel betrachten wir die Dateien, die von Prozessen geöffnet wurden, die im Besitz des Benutzers mary sind oder in ihrem Namen gestartet wurden.

sudo lsof -u mary

Alle aufgelisteten Dateien wurden im Namen des Benutzers mary geöffnet. Dazu gehören zum Beispiel Dateien, die von der Desktop-Umgebung oder durch die Anmeldung von mary geöffnet wurden.

Dateien eines Benutzers ausschließen

Um die von einem Benutzer geöffneten Dateien auszuschließen, verwenden Sie den Operator ^. Das Ausschließen von Benutzern aus der Liste kann das Auffinden relevanter Informationen erleichtern. Verwenden Sie dazu die Option -u und stellen Sie das Zeichen ^ vor dem Benutzernamen.

sudo lsof +D /home -u ^mary

Die Auflistung für das Verzeichnis /home enthält diesmal keine Dateien, die vom Benutzer mary geöffnet wurden.

Dateien anzeigen, die von einem Prozess geöffnet wurden

Um die Dateien aufzulisten, die von einem bestimmten Prozess geöffnet wurden, verwenden Sie die Option -p (Prozess) und geben Sie die Prozess-ID als Parameter an.

sudo lsof -p 4610

Alle Dateien, die mit der angegebenen Prozess-ID geöffnet wurden, werden aufgelistet.

Prozess-IDs anzeigen, die eine Datei geöffnet haben

Um die Prozess-IDs der Prozesse anzuzeigen, die eine bestimmte Datei geöffnet haben, verwenden Sie die Option -t (kurz) und geben Sie den Dateinamen in der Befehlszeile an.

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

Die Prozess-IDs werden in einer einfachen Liste angezeigt.

Verwendung von UND- und ODER-Suchen

Listen wir die Dateien auf, die von Benutzer mary geöffnet wurden und sich auf SSH-Prozesse beziehen. Wir wissen, dass wir mehrere Suchbegriffe in der Befehlszeile angeben können, also sollte das einfach sein.

sudo lsof -u mary -c ssh

Betrachten wir nun die Ausgabe von lsof. Das sieht nicht richtig aus; es gibt Einträge in der Ausgabe, die von root gestartet wurden.

Das haben wir nicht erwartet. Was ist passiert?

Wenn Sie mehrere Suchbegriffe angeben, gibt lsof jede Datei zurück, die mit dem ersten Suchbegriff oder dem zweiten Suchbegriff usw. übereinstimmt. Anders ausgedrückt, es führt eine ODER-Suche durch.

Verwenden Sie die Option -a (und), damit lsof eine UND-Suche durchführt. Das bedeutet, dass nur Dateien aufgelistet werden, die dem ersten Suchbegriff, dem zweiten Suchbegriff usw. entsprechen.

Versuchen wir es noch einmal und verwenden die Option -a.

sudo lsof -u mary -c ssh -a

Nun ist jede Datei in der Liste eine, die von oder im Namen von mary geöffnet wurde und mit dem ssh-Befehl verknüpft ist.

Automatisches Aktualisieren der Anzeige

Wir können die Option +/-r (repeat) nutzen, um lsof in den Wiederholmodus zu versetzen. Die Option kann auf zwei Arten verwendet werden: +r oder -r. Wir müssen zusätzlich die Anzahl der Sekunden angeben, die lsof warten soll, bevor die Anzeige aktualisiert wird.

Wenn Sie die Wiederholungsoption in beiden Formaten verwenden, zeigt lsof die Ergebnisse wie gewohnt an, fügt jedoch am unteren Rand der Anzeige eine gestrichelte Linie hinzu. Es wartet die in der Befehlszeile angegebene Anzahl von Sekunden und aktualisiert dann die Anzeige mit einem neuen Ergebnissatz.

Die Option -r setzt dies fort, bis Sie Strg+C drücken. Das Format +r wird solange fortgesetzt, bis keine Ergebnisse mehr angezeigt werden können oder bis Sie Strg+C drücken.

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

Beachten Sie die gestrichelte Linie am Ende der Auflistung. Sie trennt jede neue Datenanzeige, wenn die Ausgabe aktualisiert wird.

Anzeigen von Dateien, die mit Internetverbindungen verknüpft sind

Mit der Option -i (Internet) können Sie Dateien anzeigen, die von Prozessen geöffnet wurden, die mit Netzwerk- und Internetverbindungen verbunden sind.

lsof -i

Alle über Netzwerk- und Internetverbindungen geöffneten Dateien werden angezeigt.

Anzeigen von Dateien, die mit Internetverbindungen nach Prozess-ID verknüpft sind

Um die Dateien anzuzeigen, die über Internetverbindungen geöffnet wurden und einer bestimmten Prozess-ID zugeordnet sind, fügen Sie die Option -p und die Option -a hinzu.

Hier suchen wir nach Dateien, die über eine Internet- oder Netzwerkverbindung von einem Prozess mit der ID 606 geöffnet wurden.

sudo lsof -i -a -p 606

Alle mit der Prozess-ID 606 geöffneten Dateien, die Internet- oder Netzwerkverbindungen zugeordnet sind, werden angezeigt.

Anzeigen von Dateien, die mit Internetverbindungen und Befehlen verknüpft sind

Wir können die Option -c (Befehl) verwenden, um nach Dateien zu suchen, die von bestimmten Prozessen geöffnet wurden. Um nach Dateien zu suchen, die über Internet- oder Netzwerkverbindungen im Zusammenhang mit dem ssh-Prozess geöffnet wurden, verwenden Sie den folgenden Befehl:

lsof -i -a -c ssh

Alle Dateien, die aufgrund der ssh-Prozesse geöffnet wurden, werden in der Ausgabe aufgelistet.

Anzeigen von Dateien, die mit Internetverbindungen und Ports verknüpft sind

Wir können einen lsof-Bericht über die Dateien erstellen, die über Internet- oder Netzwerkverbindungen an einem bestimmten Port geöffnet wurden. Dazu verwenden wir das Zeichen : gefolgt von der Portnummer.

Hier fordern wir lsof auf, die Dateien aufzulisten, die über Netzwerk- oder Internetverbindungen über Port 22 geöffnet wurden.

lsof -i :22

Alle aufgelisteten Dateien wurden von Prozessen geöffnet, die Port 22 zugeordnet sind (der Standardport für SSH-Verbindungen).

Anzeigen von Dateien, die mit Internetverbindungen und Protokollen verknüpft sind

Wir können lsof bitten, die Dateien anzuzeigen, die von Prozessen geöffnet wurden, die mit Netzwerk- und Internetverbindungen verbunden sind und ein bestimmtes Protokoll verwenden. Wir können zwischen TCP, UDP und SMTP wählen. Betrachten wir das TCP-Protokoll.

sudo lsof -i tcp

Die einzigen aufgelisteten Dateien sind diejenigen, die von Prozessen geöffnet wurden, die das TCP-Protokoll verwenden.

Wir haben nur an der Oberfläche gekratzt

Dies ist eine solide Grundlage für einige gängige Anwendungsfälle von lsof. Es gibt jedoch noch viel mehr zu entdecken. Die Manpage ist über 2800 Zeilen lang, was die Tiefe des Befehls verdeutlicht.

Der Befehl lsof kann genutzt werden, um immer tiefer in die Schichten offener Dateien und Pseudodateien einzutauchen. Wir haben Ihnen