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.file
. Auf diese Weise lädt file die Magic-Dateien vor und verarbeitet dann die Befehlszeile Parameter für Parameter. Anstatt das Laden der Magic-Datei in den Teil "Tun Sie dies, bevor Sie herausfinden, um welche Art von Datei es sich handelt" zu verschieben, würde dies die Komplexität erhöhen. Das Aufrufenstat()
und Reagieren auf seinen Rückgabewert ist im Wesentlichen harmlos; Das Hinzufügen von Komplexität bei der Verfolgung zusätzlicher interner Zustandsrisiken, die zur Einführung von Fehlern führen.file
Datei leer ist, liegt darinstat
, dass spezielle Dateien ( Named Pipes, Geräte usw.) erkannt und die Verarbeitung leerer Dateien beendet werden.file -s /proc/version
meldet "ASCII-Text".-s
ist für Block / Char-Spezialgeräte gedacht . Schließlich schaute ich auf diefile
Quelle und am Ende von fsmagic.c sah ich diese Erklärung, warum es zurückkehrt,ASCII text
anstattempty
:If stat() tells us the file has zero length, report here that the file is empty, so we can skip all the work of opening and reading the file. But if the -s option has been given, we skip this optimization, since on some systems, stat() reports zero size for raw disk partitions.
In diesem Verzeichnis können Sie steuern, wie der Kernel Geräte anzeigt, Kerneleinstellungen anpassen, Geräte zum Kernel hinzufügen und diese wieder entfernen. In diesem Verzeichnis können Sie die Speicherauslastung und die E / A- Statistiken direkt anzeigen .
Sie können sehen, welche Festplatten gemountet sind und welche Dateisysteme verwendet werden. Kurz gesagt, jeder einzelne Aspekt Ihres Linux-Systems kann in diesem Verzeichnis untersucht werden, wenn Sie wissen, wonach Sie suchen müssen.
Das
/proc
Verzeichnis ist kein normales Verzeichnis. Wenn Sie von einer Boot-CD booten und sich dieses Verzeichnis auf Ihrer Festplatte ansehen, sehen Sie, dass es leer ist. Wenn Sie es unter Ihrem normalen Betriebssystem betrachten, kann es ziemlich groß sein. Es scheint jedoch keinen Festplattenspeicher zu belegen. Dies liegt daran, dass es sich um ein virtuelles Dateisystem handelt.Da das
/proc
Dateisystem ein virtuelles Dateisystem ist und sich im Arbeitsspeicher befindet,/proc
wird bei jedem Neustart Ihres Linux-Computers ein neues Dateisystem erstellt.Mit anderen Worten, es ist nur ein Mittel, um über eine Datei- und Verzeichnistyp-Schnittstelle auf einfache Weise in die Eingeweide des Linux-Systems zu blättern. Wenn Sie sich eine Datei im
/proc
Verzeichnis ansehen , sehen Sie direkt einen Speicherbereich im Linux-Kernel und sehen, was er sehen kann.Die Ebenen im Dateisystem
Beispiele:
/proc
befindet sich ein Verzeichnis für jeden ausgeführten Prozess, das mit seiner Prozess-ID benannt ist. Diese Verzeichnisse enthalten Dateien mit nützlichen Informationen zu den Prozessen, z.exe
: Dies ist eine symbolische Verknüpfung zu der Datei auf der Festplatte, von der aus der Prozess gestartet wurde.cwd
: Dies ist eine symbolische Verknüpfung zum Arbeitsverzeichnis des Prozesses.wchan
: Gibt beim Lesen den wartenden Kanal zurück, auf dem der Prozess läuft.maps
: Gibt beim Lesen die Speicherzuordnungen des Prozesses zurück./proc/uptime
Gibt die Betriebszeit als zwei durch ein Leerzeichen getrennte Dezimalwerte in Sekunden zurück:/proc/interrupts
: Informationen zu Interrupts./proc/modules
: Für eine Liste von Modulen.Weitere Informationen finden Sie unter man proc oder kernel.org .
quelle
mount -t procfs procfs /mnt/proc
, wird der aktuell ausgeführte Kernel / proc angezeigt.Sie haben Recht, es handelt sich nicht um echte Dateien.
Im einfachsten Fall können Sie mit den normalen Methoden zum Lesen und Schreiben von Dateien mit dem Kernel kommunizieren, anstatt den Kernel direkt aufzurufen. Dies steht im Einklang mit der Unix-Philosophie "Alles ist eine Datei".
Die Dateien in
/proc
existieren physisch nirgendwo, aber der Kernel reagiert auf die Dateien, die Sie dort lesen und schreiben, und anstatt in den Speicher zu schreiben, meldet er Informationen oder führt etwas aus.In ähnlicher Weise sind die Dateien in
/dev
nicht wirklich Dateien im herkömmlichen Sinne (obwohl auf einigen Systemen die Dateien/dev
tatsächlich auf der Festplatte vorhanden sein können, haben sie nicht viel zu bieten, außer auf welches Gerät sie sich beziehen) - sie ermöglichen es Ihnen, zu sprechen auf ein Gerät mit der normalen Unix-Datei-E / A-API - oder auf alles, was es verwendet, wie z. B. Shellsquelle
Innerhalb des
/proc
Verzeichnisses gibt es zwei Arten von Inhalten, das erste nummerierte Verzeichnis und das zweite die Systeminformationsdatei./proc
ist ein virtuelles Dateisystem. Wenn Sie dies tunls -l /proc/stat
, werden Sie zum Beispiel feststellen, dass es eine Größe von 0 Bytes hat, aber wenn Sie "cat / proc / stat" tun, werden Sie einige Inhalte in der Datei sehen.Wenn
ls -l /proc
Sie a ausführen, sehen Sie viele Verzeichnisse mit nur Zahlen. Diese Nummern repräsentieren die Prozess-IDs (PIDs). Die Dateien in diesem nummerierten Verzeichnis entsprechen dem Prozess mit dieser bestimmten PID.Einige Dateien, die unter verfügbar sind
/proc
, enthalten Systeminformationen wie cpuinfo, meminfo und loadavg.Einige Linux-Befehle lesen die Informationen aus diesen
/proc
Dateien und zeigen sie an. Beispielsweise liest der Befehl free die Speicherinformationen aus der/proc/meminfo
Datei, formatiert sie und zeigt sie an.Um mehr über die einzelnen
/proc
Dateien zu erfahren , führen Sie "man 5 FILENAME" aus.quelle
Minimal lauffähiges Beispiel
Der beste Weg, um diese Dinge zu verstehen, besteht meiner Meinung nach darin, tatsächlich damit herumzuspielen. Hier ist ein Kernel-Modul, das einen procfs-Eintrag erstellt:
myprocfs.c
und dann interagieren wir damit als:
und das ergibt die Ausgabe:
Aus diesem Beispiel geht klar hervor,
proc
dass wir mit Dateien beliebige "dateibezogene Systemaufrufe" wieopen
,read
und implementieren könnenllseek
.Diese Systemaufrufe können dann für eine beliebige Kommunikation mit dem Kernel verwendet werden.
Daher müssen diese Dateien nichts mit tatsächlichen Dateien in Dateisystemen zu tun haben, und das ist bei fast allen der Fall.
In unserem kleinen Beispiel zum Beispiel erstellen wir einfach eine unbrauchbare Datei, für die
read
immer ein Wert zurückgegeben wirdabcd\n
.Hier ist mein vollautomatisches QEMU + Buildroot-Setup zum einfachen und sicheren Erstellen und Spielen mit diesem Kernel-Modul:
Einige andere ähnliche Schnittstellen umfassen:
debugfs bietet im Grunde die gleiche Schnittstelle, weist jedoch auf eine weniger stabile API hin. Hier ein Beispiel .
Zeichengeräte sind sich ebenfalls sehr ähnlich, die Dateien werden jedoch mit
mknod
folgendem Code erstellt : https://unix.stackexchange.com/questions/37829/how-do-character-device-or-character-special-files-work/371758# 371758sysfs ist eine weitere eingeschränkte Option. Weitere Informationen finden Sie in dieser Antwort: https://unix.stackexchange.com/questions/4884/what-is-the-difference-between-procfs-and-sysfs/382315#382315
quelle