Wie ist ein Verzeichnis ein "besonderer Dateityp"?

Antworten:

19

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

ist ein abstrakter Indikator für den Zugriff auf eine Datei oder eine andere Eingabe- / Ausgaberessource , z. B. eine Pipe oder eine Netzwerkverbindung.

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 .

Goldlöckchen
quelle
2
POSIX.1-2008 fügte eine Reihe von Systemaufrufen ( openat, fstatatusw.) hinzu, die Dateideskriptoren verwenden, die auf Verzeichnisse verweisen.
zwol
2
Noch interessanter ist, dass Sie 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).
Kevin
13

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:

  • links
  • Steckdosen
  • Geräte

Da sie jedoch als "Dateien" betrachtet werden, können Sie lssie umbenennen und verschieben und je nach Art der speziellen Datei Daten an diese senden.

Hymie
quelle
1
Und das macht das Leben viel einfacher, weil Sie nichts anderes tun müssen, nur weil es sich um ein Verzeichnis handelt. Dies gilt sowohl für das Schreiben von Programmen als auch für Operationen über die Befehlszeile (oder GUI).
Gbarry
1
Ein Verzeichnis enthält Daten: Die Daten, die die im Verzeichnis enthaltenen Dateien beschreiben. Es ist durchaus möglich, auf ein Verzeichnis zuzugreifen (wenn auch nicht mit einem normalen offenen Anruf) und diese Daten selbst zu lesen, obwohl (wie Bruce Ediger in seiner Antwort feststellt) die Daten nur von Nutzen sind, wenn Sie das Format kennen.
Jamesqf
11

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/includedie 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.

Bruce Ediger
quelle
1
Bei einigen Unix-Varianten können Sie ein Verzeichnis noch heute öffnen und als Datei lesen, zum Beispiel ist dies unter FreeBSD 10.1 immer noch möglich. (Can ≠ should)
Gilles 'SO - hör auf böse zu sein'
@ Gilles Ich denke, es wäre sehr logisch, wenn ein Verzeichnis, das von dd kopiert wird, im Wesentlichen dem entspricht cp --link dir1/* dir2, obwohl ich nicht sicher bin, ob es brauchbar ist.
Peterh sagt, dass er Monica
3

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.

Psusi
quelle
Bei allen Dateisystemen ist das nicht so einfach - wenn ich mich recht erinnere, gibt es zum Beispiel in Apples HFS + nur einen großen B + -Baum, der alle Pfadnamen enthält -, aber diese Beobachtung ist für Unix-Dateisysteme bis einschließlich BSDs ffs genau richtig ist wahrscheinlich das, woran die Autoren des zitierten Tutorials gedacht haben.
zwol
2

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.

Henri Kynsilehto
quelle
-3

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.

Rick
quelle
2
Nein, nur 1 Inode kann auf dieselbe Datei verweisen. Derselbe Inode kann zwar gleichzeitig in mehreren Verzeichnissen (oder unter mehreren Namen) vorhanden sein. Eine einfache Kontrolle: 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.
Peter sagt, Monica
@peterh Dateideskriptoren sind nur für einen Prozess eindeutig. können Sie erklären?
Alamin
1
@ Md.AlaminMahamud Es ist nicht wahr, wenn ein Prozess fork()s, sein untergeordneter Prozess (mit Ausnahme einiger besonderer Umstände, nämlich eines O_CLOEXECFlags) genau die gleichen Filedescriptor-Entitäten hat wie der ursprüngliche Prozess. Ein weiteres Beispiel: Untergeordnete Apache-Prozesse befinden sich listen()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).
Peter sagt, Monica 20.04.18
1
@ Md.AlaminMahamud Naja, jetzt bin ich mir nicht ganz sicher, ob zum Beispiel ein fork()Ereignis und dann der seek()oder die untergeordneten Prozesse close()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.
Peter sagt, Monica