Es ist eigentlich ziemlich einfach, zumindest wenn Sie die Implementierungsdetails nicht benötigen.
Zunächst werden unter Linux alle Dateisysteme (ext2, ext3, btrfs, reiserfs, tmpfs, zfs, ...) im Kernel implementiert. Einige können die Arbeit über FUSE in den Userland-Code verlagern, andere nur in Form eines Kernelmoduls ( natives ZFS ist aufgrund von Lizenzbeschränkungen ein bemerkenswertes Beispiel für letzteres), aber so oder so bleibt eine Kernelkomponente erhalten. Dies ist eine wichtige Grundvoraussetzung.
Wenn ein Programm will aus einer Datei lesen, wird es verschiedene Systembibliothek Anrufe ausgeben , die letztlich im Kern in Form eines am Ende open()
, read()
, close()
Sequenz (möglicherweise mit seek()
für eine gute Maßnahme geworfen). Der Kernel verwendet den angegebenen Pfad und Dateinamen und übersetzt diese über das Dateisystem und die Geräte-E / A-Ebene in physische Leseanforderungen (und in vielen Fällen auch in Schreibanforderungen - denken Sie beispielsweise an Zeitaktualisierungen) in einen zugrunde liegenden Speicher.
Diese Anforderungen müssen jedoch nicht speziell in physischen, dauerhaften Speicher übersetzt werden . Der Kernel-Vertrag sieht vor, dass durch das Ausgeben dieser bestimmten Systemaufrufe der Inhalt der betreffenden Datei bereitgestellt wird . Wo genau in unserem physischen Bereich die "Datei" existiert, ist zweitrangig.
Auf /proc
ist in der Regel das montiert, was als bekannt ist procfs
. Das ist ein spezieller Dateisystemtyp, aber da es sich um ein Dateisystem handelt, unterscheidet es sich nicht wirklich von z. B. einem ext3
Dateisystem, das irgendwo angehängt ist. Die Anforderung wird also an den procfs-Dateisystemtreibercode übergeben, der alle diese Dateien und Verzeichnisse kennt und bestimmte Informationen aus den Kerneldatenstrukturen zurückgibt .
Die "Speicherschicht" ist in diesem Fall die Kerneldatenstruktur und procfs
bietet eine saubere, bequeme Schnittstelle für den Zugriff auf diese. Denken Sie daran, dass das Mounten von procfs at /proc
nur eine Konvention ist. Sie können es genauso einfach an einer anderen Stelle anbringen. Tatsächlich geschieht dies manchmal, zum Beispiel in Chroot-Gefängnissen, wenn der dort ausgeführte Prozess aus irgendeinem Grund Zugriff auf / proc benötigt.
Das funktioniert genauso, wenn Sie einen Wert in eine Datei schreiben. auf Kernel - Ebene, übersetzt , die zu einer Reihe von open()
, seek()
, write()
, close()
Anrufen , die wieder in den Dateisystem - Treiber übergeben bekommen; in diesem speziellen Fall wieder der procfs-Code.
Der besondere Grund für die file
Rückkehr empty
ist, dass viele der von procfs bereitgestellten Dateien eine Größe von 0 Byte aufweisen. Die 0-Byte-Größe ist wahrscheinlich eine Optimierung auf der Kernelseite (viele der Dateien in / proc sind dynamisch und können leicht in der Länge variieren, möglicherweise sogar von einem Lesevorgang zum nächsten, und die Länge jeder Datei in jedem gelesenen Verzeichnis berechnen möglicherweise sehr teuer sein). Going durch die Kommentare zu dieser Antwort, die Sie auf Ihrem eigenes System , indem Sie durch strace oder ein ähnliches Werkzeug, überprüfen können file
ausstellt zunächst einen stat()
Anruf spezielle Dateien zu erkennen, und nimmt dann die Möglichkeit, falls die Dateigröße gemeldet als 0 , brechen Sie die Datei ab und melden Sie sie als leer.
Dieses Verhalten ist tatsächlich dokumentiert und kann durch Angabe -s
oder --special-files
beim file
Aufruf außer Kraft gesetzt werden , obwohl dies auf der Handbuchseite angegeben ist, die möglicherweise Nebenwirkungen hat. Das folgende Zitat stammt aus der BSD-Manpage 5.11 vom 17. Oktober 2011.
Normalerweise versucht file nur, den Typ der Argumentdateien zu lesen und zu bestimmen, die stat (2) als normale Dateien ausgibt. Dies verhindert Probleme, da das Lesen spezieller Dateien besondere Konsequenzen haben kann. Durch die Angabe der -s
Option liest file auch Argumentdateien, die Block- oder Zeichenspezialdateien sind. Dies ist nützlich, um die Dateisystemtypen der Daten in unformatierten Festplattenpartitionen zu bestimmen, bei denen es sich um spezielle Blockdateien handelt. Diese Option bewirkt auch, dass die Datei die von stat (2) gemeldete Dateigröße ignoriert, da auf einigen Systemen eine Größe von Null für unformatierte Festplattenpartitionen gemeldet wird .
strace file /proc/version
oder betrachtenltrace -S /proc/version
, ist die Optimierung eher gering. Es führt zuerst einenstat()
Aufruf durch und stellt fest, dass die Größe 0 ist. Dadurch wird der Befehl übersprungen.open()
Vorher werden jedoch mehrere Magic-Dateien geladen.