Unter Unix ist eine Datei normalerweise ein Eintrag in einer Dateitabelle. Es gibt verschiedene Arten von Dateien: normale Dateien, Geräte, symbolische Links, Türen, Rohre, Steckdosen, Verzeichnisse ...
Die Inode-Nummer (die Sie in der Ausgabe von sehen können ls -i
) ist der Index in dieser Tabelle.
Jetzt greifen Sie nicht mehr über den Inode, sondern über den Pfad auf Dateien zu . Ein Pfad ist eine Kette von Verzeichniseinträgen . Sie werden feststellen, dass es sich hier nicht um einen Ordner, sondern um ein Verzeichnis handelt . Weil es das ist, was ein Verzeichnis ist (denken Sie an ein Telefonverzeichnis).
Ein Verzeichnis ist eine spezielle Art von Datei, die einer Reihe von Inodes Namen gibt. Ein Verzeichniseintrag ist eine Zuordnung von einem Namen zu einem Inode.
Eine bestimmte Datei (ein Inode) kann mehr als einen Namen in einem Verzeichnis haben (genau wie es mehr als einen Namen in einer Telefonnummer geben kann) und kann auch Namen (Einträge) in mehr als einem Verzeichnis haben. Diese werden genannt Links auch bekannt als harte Links mit unterscheiden Softlinks (eine spezielle Art von Datei , die ein Zeiger auf einen Pfad ist).
Eine Datei (Inode) protokolliert die Anzahl der Verknüpfungen (der Einträge in einem beliebigen Verzeichnis), über die sie verfügt, sodass die Zuordnung aufgehoben wird, wenn die Anzahl 0 erreicht (wenn die Verknüpfung zum letzten Verzeichnis, auf das verwiesen wurde, aufgehoben wird).
Das ist die Nummer (die Anzahl der Links), die in der ls -l
Ausgabe angezeigt wird.
Wenn eine Nicht-Verzeichnis - Datei zum ersten Mal erstellt wird (mit open
oder creat
(oder bind
oder mknod
für einige Arten von Dateien) Systemaufrufe), wird durch die Bereitstellung mit einem Weg in die neuen Datei getan (wie "/a/b"
). Was dann passiert, ist, dass eine neue Datei und ein neuer Inode zugewiesen werden und dem Verzeichnis, das dem "a"
Namen im "/"
Stammverzeichnis zugeordnet ist, ein neuer Eintrag hinzugefügt wird . Das ist der ursprüngliche Link , die Anzahl der Links ist also eins.
Weitere Links können später mit dem link()
Systemaufruf (dem ln
Befehl) hinzugefügt werden . Und Verknüpfungen können mit dem unlink()
Systemaufruf (dem rm
Befehl) entfernt werden.
Sie werden feststellen , dass die Dateien vom Typ Verzeichnis im Allgemeinen eine Reihe von Links größer oder gleich 2.
Wenn Sie jetzt ein Verzeichnis erstellen, rufen Sie den mkdir()
Systemaufruf auf. So etwas wie mkdir("/a/b")
. Was es dann tut, ist das Zuweisen einer neuen Datei vom Typ Verzeichnis. In diesem neuen Verzeichnis werden automatisch zwei Einträge erstellt:
"."
( Punkt für Verzeichnis ). Welches ist eine Verbindung zu sich selbst. Die Anzahl der Links ist jetzt 1.
".."
(für das Verzeichnis des Verzeichnisses ). Welches ist ein Link zu "/a"
. Die Anzahl der Links von "/a"
wird also um eins erhöht
Dann wird dieses neue Verzeichnis mit verknüpft "/a"
(ein Eintrag wird dafür hinzugefügt "/a"
), so dass seine Verknüpfungsanzahl jetzt 2 ist. Wenn ein "/a/b/c"
Verzeichnis aufgrund des ".."
Eintrags in erstellt wird "/a/b/c"
, wird die Verknüpfungsanzahl von "/a/b"
3.
Die meisten Unices beschränken das Erstellen weiterer Links zu einem Verzeichnis, da dies zu problematischen Schleifen führen kann. Wenn ein link()
in einem Verzeichnis zulässig ist, kann dies im Allgemeinen nur der Superuser.
Einige Dateisysteme btrfs
weichen von dieser traditionellen Verzeichnisstruktur ab. Sie werden feststellen, dass die Anzahl der Verknüpfungen in Verzeichnissen in btrfs
Dateisystemen immer eins ist, obwohl diese Verzeichnisse einen "."
Eintrag mit derselben Inode-Nummer enthalten wie sie.
Die Tatsache, dass die Anzahl der Verknüpfungen traditionell 2 plus der Anzahl der Unterverzeichnisse beträgt, hat seinen Zweck. Zum Beispiel in:
find . -name '*.c' -print
If .
enthält keine Unterverzeichnisse, sondern Millionen von Dateien. Durch Überprüfen der Linkanzahl von .
kann find
festgestellt werden, dass es kein Unterverzeichnis gibt. Alles find
, was Sie tun müssen, ist, den Inhalt des Verzeichnisses zu lesen und die Einträge zu melden, die auf enden .c
(wie grep '\.c$'
eine wenige Megabyte große Datei, keine große Sache). Andernfalls find
müsste der Typ jeder einzelnen Datei überprüft werden, um festzustellen, ob Verzeichnisse vorhanden sind, in die er absteigen kann (was zu so vielen lstat()
Systemaufrufen führt). Natürlich funktioniert diese Art der Optimierung nicht btrfs
(obwohl in modernen Linux-Versionen der Dateityp für einige Dateisysteme (einschließlich btrfs
) auch im Verzeichniseintrag gespeichert und vom getdents(2)
Systemaufruf zurückgegeben wird, der zum Abrufen der Liste der Einträge verwendet wird in einem Verzeichnis, alsolstat
ist noch nicht nötig).