Was wäre eine vereinfachte Beschreibung von Dateideskriptoren im Vergleich zu Wikipedia? Warum werden sie benötigt? Nehmen wir als Beispiel Shell-Prozesse und wie trifft dies zu?
Enthält eine Prozesstabelle mehr als einen Dateideskriptor? Wenn ja, warum?
unix
operating-system
file-descriptor
Nishant
quelle
quelle
Antworten:
Mit einfachen Worten, wenn Sie eine Datei öffnen, erstellt das Betriebssystem einen Eintrag, um diese Datei darzustellen und die Informationen zu dieser geöffneten Datei zu speichern. Wenn also 100 Dateien in Ihrem Betriebssystem geöffnet sind, gibt es 100 Einträge im Betriebssystem (irgendwo im Kernel). Diese Einträge werden durch ganze Zahlen wie (... 100, 101, 102 ....) dargestellt. Diese Eintragsnummer ist der Dateideskriptor. Es handelt sich also nur um eine Ganzzahl, die eine geöffnete Datei im Betriebssystem eindeutig darstellt. Wenn Ihr Prozess 10 Dateien öffnet, enthält Ihre Prozesstabelle 10 Einträge für Dateideskriptoren.
Wenn Sie einen Netzwerk-Socket öffnen, wird dieser ebenfalls durch eine Ganzzahl dargestellt und als Socket-Deskriptor bezeichnet. Ich hoffe, Sie verstehen.
quelle
/proc
ständig Deskriptoren öffnen .open()
gibt Ihnen den Dateideskriptor 3, auch wenn ein anderer laufender Prozess zufällig einen Dateideskriptor 3 hat. Siehe die POSIX-Definition vonopen()
: "Die Funktion open () gibt einen Dateideskriptor für die benannte Datei zurück, der der niedrigste ist Dateideskriptor für diesen Prozess derzeit nicht geöffnet . " (Betonung hinzugefügt).Ein Dateideskriptor ist ein undurchsichtiges Handle, das in der Schnittstelle zwischen Benutzer- und Kernelbereich verwendet wird, um Datei- / Socket-Ressourcen zu identifizieren. Wenn Sie also
open()
odersocket()
(Systemaufrufe zur Schnittstelle zum Kernel) verwenden, erhalten Sie einen Dateideskriptor, der eine Ganzzahl ist (es ist tatsächlich ein Index für die Prozess-u-Struktur - aber das ist nicht wichtig). Wenn Sie eine direkte Schnittstelle zum Kernel, Systemaufrufe usw. verwenden möchtenread()
,write()
istclose()
das von Ihnen verwendete Handle daher ein Dateideskriptor.Den Systemaufrufen wird eine Abstraktionsebene überlagert, bei der es sich um die
stdio
Schnittstelle handelt. Dies bietet mehr Funktionen / Features als die grundlegenden Systemaufrufe. Für diese Schnittstelle ist das undurchsichtige Handle einFILE*
, das vomfopen()
Aufruf zurückgegeben wird. Es gibt viele , viele Funktionen, die die Verwendungstdio
Schnittstellefprintf()
,fscanf()
,fclose()
, die gibt es Ihnen das Leben leichter zu machen. In Cstdin
,stdout
undstderr
sindFILE*
, die in UNIX Karte jeweils Dateideskriptoren0
,1
und2
.quelle
Hören Sie es aus dem Maul des Pferdes: APUE (Richard Stevens).
Für den Kernel werden alle geöffneten Dateien von Dateideskriptoren referenziert. Ein Dateideskriptor ist eine nicht negative Zahl.
Wenn wir eine vorhandene Datei öffnen oder eine neue Datei erstellen, gibt der Kernel einen Dateideskriptor an den Prozess zurück. Der Kernel verwaltet eine Tabelle aller geöffneten Dateideskriptoren, die verwendet werden. Die Zuweisung von Dateideskriptoren erfolgt im Allgemeinen sequentiell und sie werden der Datei als nächster freier Dateideskriptor aus dem Pool der freien Dateideskriptoren zugewiesen. Wenn wir die Datei schließen, wird der Dateideskriptor freigegeben und steht für die weitere Zuordnung zur Verfügung.
Siehe dieses Bild für weitere Details:
Wenn wir eine Datei lesen oder schreiben möchten, identifizieren wir die Datei mit dem Dateideskriptor, der vom Funktionsaufruf open () oder create () zurückgegeben wurde , und verwenden ihn als Argument für read () oder write () .
Es ist üblich, dass UNIX-System-Shells den Dateideskriptor 0 mit der Standardeingabe eines Prozesses, den Dateideskriptor 1 mit der Standardausgabe und den Dateideskriptor 2 mit dem Standardfehler verknüpfen .
Der Dateideskriptor reicht von 0 bis OPEN_MAX. Der maximale Wert des Dateideskriptors kann mit erhalten werden
ulimit -n
. Weitere Informationen finden Sie im 3. Kapitel des APUE-Buches.quelle
osqueryi <<< echo '.all process_open_files'
in einer Bash-Shell aus.Andere Antworten fügten großartige Dinge hinzu. Ich werde nur meine 2 Cent hinzufügen.
Laut Wikipedia wissen wir sicher: Ein Dateideskriptor ist eine nicht negative Ganzzahl. Das Wichtigste, was mir fehlt, wäre zu sagen:
Dateideskriptoren sind an eine Prozess-ID gebunden.
Wir wissen, dass die bekanntesten Dateideskriptoren 0, 1 und 2 sind. 0 entspricht
STDIN
, 1 bisSTDOUT
und 2 bisSTDERR
.Überprüfen Sie diesen Code
Wir haben einen Prozess mit der ID 14726 (PID) erstellt. Mit dem können
lsof -p 14726
wir die Dinge wie folgt bekommen:Die 4. Spalte FD und die nächste Spalte TYPE entsprechen dem Dateideskriptor und dem Dateideskriptortyp.
Einige der Werte für die FD können sein:
Der eigentliche Dateideskriptor befindet sich jedoch unter:
Das Zeichen nach der Zahl, dh "1u", repräsentiert den Modus, in dem die Datei geöffnet wird. r zum Lesen, w zum Schreiben, u zum Lesen und Schreiben.
TYPE gibt den Dateityp an. Einige der Werte von TYPEs sind:
Alle Dateideskriptoren sind jedoch CHR - Character Special File (oder Character Device File).
Jetzt können wir die Dateideskriptoren für identifizieren
STDIN
,STDOUT
undSTDERR
einfach mitlsof -p PID
, oder wir können das gleiche , wenn wir sehenls /proc/PID/fd
.Beachten Sie auch, dass die Dateideskriptortabelle, die der Kernel verfolgt, nicht mit der Dateitabelle oder der Inodes-Tabelle identisch ist. Diese sind getrennt, wie einige andere Antworten erklärt haben.
Sie fragen sich, wo diese Filedeskriptoren physisch sind und was gespeichert ist
/dev/pts/6
zum BeispielNun,
/dev/pts/6
lebt nur in Erinnerung. Dies sind keine regulären Dateien, sondern sogenannte Zeichengerätedateien . Sie können dies überprüfen mit:ls -l /dev/pts/6
und sie beginnenc
in meinem Fall mitcrw--w----
.Um sich an die meisten Linux-ähnlichen Betriebssysteme zu erinnern, definieren Sie sieben Dateitypen:
quelle
Weitere Punkte zu
File Descriptor
:File Descriptors
(FD) sind nicht negative Ganzzahlen(0, 1, 2, ...)
, die geöffneten Dateien zugeordnet sind.0, 1, 2
ist Standard FD ‚Das entspricht sSTDIN_FILENO
,STDOUT_FILENO
undSTDERR_FILENO
(definiert inunistd.h
standardmäßig im Namen von Shell , wenn die Programmstarts geöffnet).FDs werden in der sequentiellen Reihenfolge zugewiesen, was den niedrigstmöglichen nicht zugewiesenen ganzzahligen Wert bedeutet.
FDs für einen bestimmten Prozess sind in
/proc/$pid/fd
(auf Unix-basierten Systemen) zu sehen.quelle
Als Ergänzung zu anderen Antworten betrachtet Unix alles als Dateisystem. Ihre Tastatur ist eine Datei, die nur aus der Sicht des Kernels gelesen werden kann. Der Bildschirm ist eine Nur-Schreib-Datei. Ebenso werden Ordner, Eingabe- / Ausgabegeräte usw. als Dateien betrachtet. Wenn eine Datei geöffnet wird, z. B. wenn die Gerätetreiber [für Gerätedateien] ein open () anfordern oder ein Prozess eine Benutzerdatei öffnet, weist der Kernel einen Dateideskriptor zu, eine Ganzzahl, die den Zugriff auf diese Datei angibt, sodass sie schreibgeschützt ist , schreibe nur usw. [als Referenz: https://en.wikipedia.org/wiki/Everything_is_a_file ]
quelle
Dateideskriptoren (FD):
Fehlerumleitung:
Immer wenn Sie ein Programm / einen Befehl am Terminal ausführen, sind 3 Dateien geöffnet
Diese Dateien sind immer vorhanden, wenn ein Programm ausgeführt wird. Wie bereits erläutert, ist jeder dieser Dateien ein Dateideskriptor zugeordnet.
Datei - File Descriptor
Standardeingabe STDIN 0
Standardausgabe STDOUT 1
Standardfehler STDERR 2
Beispiel 1
Der Dateideskriptor für Standardfehler ist 2.
Wenn kein Verzeichnis mit dem Namen mydir vorhanden ist, wird die Ausgabe des Befehls in der Datei errorfile.txt gespeichert.
Mit "2>" leiten wir die Fehlerausgabe in eine Datei mit dem Namen "errorfile" um. txt "
Somit ist die Programmausgabe nicht mit Fehlern überfüllt.
Ich hoffe du hast deine Antwort bekommen.
quelle
Auf jedem Betriebssystem werden Prozesse ( ps ) ausgeführt, z. B. p1, p2, p3 usw. Bei jedem Prozess werden normalerweise Dateien fortlaufend verwendet.
Jeder Prozess besteht aus einem Prozessbaum (oder einer Prozesstabelle in einer anderen Formulierung).
Normalerweise stellen Betriebssysteme jede Datei in jedem Prozess durch eine Zahl dar (dh in jedem Prozessbaum / jeder Tabelle).
Die erste im Prozess verwendete Datei ist Datei0 , die zweite ist Datei1 , die dritte ist Datei2 und so weiter.
Jede solche Nummer ist ein Dateideskriptor.
Dateideskriptoren sind normalerweise ganze Zahlen (0, 1, 2 und nicht 0,5, 1,5, 2,5).
Da wir Prozesse häufig als "Prozesstabellen" beschreiben und Tabellen Tabellen (Einträge) enthalten, können wir sagen, dass die Dateideskriptorzelle in jedem Eintrag den gesamten Eintrag darstellt.
In ähnlicher Weise verfügt ein Netzwerk-Socket beim Öffnen über einen Socket-Deskriptor.
In einigen Betriebssystemen gehen Ihnen möglicherweise die Dateideskriptoren aus, aber ein solcher Fall ist äußerst selten, und der durchschnittliche Computerbenutzer sollte sich darüber keine Sorgen machen.
Dateideskriptoren können global sein (Prozess A beginnt mit 0 und endet mit 1; Prozess B beginnt mit 2 und endet mit 3) und so weiter, aber soweit ich weiß, normalerweise in modernen Betriebssystemen, Datei Deskriptoren sind nicht global und tatsächlich prozessspezifisch (Prozess A beginnt mit 0 und endet mit 5, während Prozess B mit 0 beginnt und mit 10 endet).
quelle
Dateideskriptoren
quelle
Ergänzung zu vor allem vereinfachten Antworten.
Wenn Sie mit Dateien im Bash-Skript arbeiten, ist es besser, den Dateideskriptor zu verwenden.
Zum Beispiel: -
Sie möchten von / in die Datei "test.txt" lesen und schreiben.
Verwenden Sie den Dateideskriptor wie unten gezeigt
quelle
Dateideskriptoren sind die Deskriptoren einer Datei. Sie geben Links zu einer Datei. Mit ihrer Hilfe können wir eine Datei lesen, schreiben und öffnen.
quelle