Ich lese dieses Unix-Tutorial und bin auf dieses Zitat gestoßen ...
Wir sollten hier beachten, dass ein Verzeichnis lediglich ein spezieller Dateityp ist.
... aber es werden keine Erklärungen oder Details geliefert. Wie ist ein Verzeichnis eigentlich nur eine Datei?
Antworten:
Viele Entitäten in * nix-ähnlichen (und anderen) Betriebssystemen werden als Dateien betrachtet oder haben einen definierenden dateiähnlichen Aspekt, obwohl sie nicht unbedingt eine Folge von Bytes sind, die in einem Dateisystem gespeichert sind. Wie Verzeichnisse genau implementiert werden, hängt von der Art des Dateisystems ab. Was sie jedoch als Liste enthalten, ist im Allgemeinen eine Folge gespeicherter Bytes. In diesem Sinne sind sie nicht besonders.
Eine Möglichkeit, zu definieren, was eine "Datei" in einem * nix-Kontext ist, besteht darin, dass ihr ein Dateideskriptor zugeordnet ist. Laut Wikipedia-Artikel ein Dateideskriptor
Mit anderen Worten, sie beziehen sich auf verschiedene Arten von Ressourcen, aus denen eine Folge von Bytes gelesen / geschrieben werden kann, obwohl die Quelle / das Ziel dieser Folge nicht spezifiziert ist. Anders ausgedrückt, das "Wo" der Ressource könnte alles sein. Was es ausmacht, ist, dass es ein Informationsfluss ist. Dies ist ein Teil des Grundes, warum manchmal gesagt wird, dass unter Unix "alles eine Datei ist". Sie sollten das nicht ganz wörtlich nehmen, aber es ist eine ernsthafte Überlegung wert. Im Fall eines Verzeichnisses beziehen sich diese Informationen auf den Inhalt des Verzeichnisses und auf einer niedrigeren Implementierungsebene darauf, wie sie im Dateisystem zu finden sind.
In diesem Sinne sind Verzeichnisse etwas Besonderes, da sie im nativen C-Code nicht angeblich mit einem Dateideskriptor verknüpft sind. Die POSIX-API verwendet einen speziellen Typ von Stream-Handle
DIR*
. Dieser Typ hat jedoch tatsächlich einen zugrunde liegenden Deskriptor, der abgerufen werden kann . Deskriptoren werden vom Kernel verwaltet, und der Zugriff auf sie erfordert immer Systemaufrufe. Ein weiterer Aspekt eines Deskriptors besteht darin, dass es sich um ein Conduit handelt, das vom Betriebssystemkern gesteuert wird. Sie haben eindeutige (pro Prozess) Nummern, die mit 0 beginnen. Dies ist normalerweise der Deskriptor für den Standardeingabestream .quelle
openat
,fstatat
usw.) hinzu, die Dateideskriptoren verwenden, die auf Verzeichnisse verweisen.fsync()
ein schreibgeschütztes (!) Verzeichnis fd erstellen können, das einen genau definierten Effekt hat (insbesondere das Erstellen / Umbenennen / Löschen von Dateien im angegebenen Verzeichnis auf die Festplatte, ein theoretisch notwendiger Schritt beim "Schreiben") in eine temporäre Datei und benennen Sie sie über die ursprüngliche "Redewendung).Unter Unix: Alles ist eine Datei.
Ein Verzeichnis ist eine (von vielen) Arten spezieller Dateien. Es enthält keine Daten. Stattdessen enthält es Zeiger auf alle Dateien, die im Verzeichnis enthalten sind.
Andere Arten von Spezialdateien:
Da sie jedoch als "Dateien" betrachtet werden, können Sie
ls
sie umbenennen und verschieben und je nach Art der speziellen Datei Daten an diese senden.quelle
Meine Antwort ist bloße Reminiszenz, aber in 199x Vintage-Unixes, von denen es viele gab, waren Verzeichnisse Dateien, die nur irgendwo auf der Festplatte als "Verzeichnis" markiert waren.
Sie könnten ein Verzeichnis mit so etwas wie öffnen
open(".", O_RDONLY)
und einen verwendbaren Dateideskriptor zurückbekommen. Sie könnten den Inhalt analysieren, wenn Sie/usr/include
die korrekte C-Strukturdefinition gefunden hätten. Ich weiß, dass ich dies für SunOS 4.1.x-Systeme, das EFS-Dateisystem von SGI und die Mips-CPU-Workstations von DEC für ein Dateisystem getan habe, wahrscheinlich BSD4.2 FFS.Das war eine schlechte Erfahrung. Die Standardisierung auf einer virtuellen Dateisystemebene ist eine gute Sache für die Portabilität, auch wenn Verzeichnisse keine strengen Dateien mehr sind. Mit VFS-Layern können wir mit Dateisystemen experimentieren, in denen Verzeichnisse keine Dateien sind, z. B. ReiserFS oder NFS.
quelle
cp --link dir1/* dir2
, obwohl ich nicht sicher bin, ob es brauchbar ist.Ein Verzeichnis ist insofern besonders, als es das 'd' in seinem Modus hat, das dem Dateisystem mitteilt, dass es seinen Inhalt als Liste anderer im Verzeichnis enthaltener Dateien interpretieren soll und nicht als reguläre Datei, die nur eine Folge von Bytes ist von der Anwendung gelesen. Das ist alles.
quelle
Verzeichnisse sind Dateien, da Linux-Systeme ein universelles E / A-Modell verwenden . Im Modell ist alles im System eine Datei, auf die mit denselben Systemaufrufen und verschiedenen Befehlen zugegriffen werden kann.
Sie sind von besonderem Typ, weil ihre i-Knoten die Markierung für den Dateityp haben und sie eine besondere Struktur haben, nämlich eine Tabelle mit Dateinamen und Verknüpfungen zu anderen i-Knoten. Diese Dateinamen-Link-Paare, auch als "Hardlinks" bezeichnet, im i-Node eines Verzeichnisses führen die Dateien "innerhalb" des Verzeichnisses auf.
Verzeichnisse dienen nur zum Organisieren von Dateien. Wenn eine Datei von einem Verzeichnis in ein anderes "verschoben" wird, wird die Datei selbst nicht auf der Festplatte verschoben. Es ist nur so, dass ein Eintrag in einem Verzeichnis-i-Knoten entfernt und in ein anderes Verzeichnis-i-Knoten geschrieben wird.
quelle
Die akzeptierte Antwort ist nicht ganz richtig. In POSIX-Systemen verweisen "Inodes" auf Dateien und Verzeichnisse. Dateideskriptoren sind nur prozessspezifisch und nicht systemübergreifend. Inodes sind jedoch eindeutig, obwohl mehr als ein Inode auf eine einzelne Datei verweisen kann. Hätte die akzeptierte Antwort kommentiert, konnte aber aufgrund von Wiederholungseinschränkungen nicht.
quelle
ls -l >test.txt;ln -vf test.txt test2.txt;ls -li test.txt test2.txt
. Sie werden sehen, dass Hardlinks dieselbe Inode-Nummer haben.fork()
s, sein untergeordneter Prozess (mit Ausnahme einiger besonderer Umstände, nämlich einesO_CLOEXEC
Flags) genau die gleichen Filedescriptor-Entitäten hat wie der ursprüngliche Prozess. Ein weiteres Beispiel: Untergeordnete Apache-Prozesse befinden sichlisten()
im selben Socket-Dateideskriptor. Bei dieser Antwort geht es jedoch nicht um die Dateideskriptoren, die eine kerninterne Datenstruktur darstellen und nur im Kernelspeicher vorhanden sind. Bei dieser ( falschen ) Antwort handelt es sich um die Verzeichniseinträge und die Inodes, dies sind Entitäten auf der Festplatte (dh es handelt sich um physische Bytes auf der Festplatte).fork()
Ereignis und dann derseek()
oder die untergeordneten Prozesseclose()
den Dateideskriptor der übergeordneten nicht beeinflussen. Daher denke ich jetzt, dass die Dateideskriptoren nur teilweise prozessprivate Strukturen sind. Aber bei dieser Frage geht es nicht um sie, sondern um die dirents / inodes, und ich kommentiere eine völlig falsche Antwort auf diese Frage.