Ein Dateideskriptor ist eine Nummer, die eine geöffnete Datei im Betriebssystem eines Computers eindeutig identifiziert. Es beschreibt eine Datenressource und wie auf diese Ressource zugegriffen werden kann.
Wenn ein Programm auffordert, eine Datei – oder eine andere Datenressource, wie einen Netzwerk-Socket – zu öffnen, führt der Kernel Folgendes aus:
- Gewährt Zugriff.
- Erstellt einen Eintrag in der globalen Dateitabelle.
- Versorgt die Software mit dem Speicherort dieses Eintrags.
Der Deskriptor wird durch eine eindeutige, nicht negative Ganzzahl identifiziert, z. B. 0, 12 oder 567. Für jede geöffnete Datei im System existiert mindestens ein Dateideskriptor.
Dateideskriptoren wurden erstmals in Unix verwendet und werden von modernen Betriebssystemen wie Linux, macOS und BSD verwendet. In Microsoft Windows werden Dateideskriptoren als Dateihandles bezeichnet.
Überblick
Wenn ein Prozess eine erfolgreiche Anfrage zum Öffnen einer Datei stellt, gibt der Kernel einen Dateideskriptor zurück, der auf einen Eintrag in der globalen Dateitabelle des Kernels zeigt. Der Dateitabelleneintrag enthält Informationen wie den Inode der Datei, den Byte-Offset und die Zugriffsbeschränkungen für diesen Datenstrom (Nur-Lesen, Nur-Schreiben usw.).
Stdin, stdout und stderr
Auf einem Unix-ähnlichen Betriebssystem sind die ersten drei Dateideskriptoren standardmäßig STDIN (Standardeingabe), STDOUT (Standardausgabe) und STDERR (Standardfehler).
Name | Dateideskriptor | Beschreibung | Abkürzung |
---|---|---|---|
Standardeingabe | 0 | Der Standarddatenstrom für die Eingabe, beispielsweise in einer Befehlspipeline. Im Terminal ist dies standardmäßig die Tastatureingabe des Benutzers. | stdin |
Standardausgabe | 1 | Der Standarddatenstrom für die Ausgabe, beispielsweise wenn ein Befehl Text druckt. Im Terminal ist dies standardmäßig der Bildschirm des Benutzers. | stdout |
Standart Fehler | 2 | Der Standarddatenstrom für die Ausgabe, die sich auf einen aufgetretenen Fehler bezieht. Im Terminal ist dies standardmäßig der Bildschirm des Benutzers. | stderr |
Dateideskriptoren umleiten
Auf Dateideskriptoren kann direkt mit Bash zugegriffen werden, der Standard-Shell von Linux, macOS X und dem Windows-Subsystem für Linux.
Wenn Sie beispielsweise den Befehl find verwenden, wird die erfolgreiche Ausgabe an stdout (Dateideskriptor 1) und Fehlermeldungen an stderr (Dateideskriptor 2) gesendet. Beide Streams werden als Terminalausgabe angezeigt:
find / -name '*something*'
/usr/share/doc/something /usr/share/doc/something/examples/something_random find: `/run/udisks2': Permission denied find: `/run/wpa_supplicant': Permission denied /usr/share/something /usr/games/something
Wir erhalten Fehler, weil find versucht, einige Systemverzeichnisse zu durchsuchen, für die wir keine Leseberechtigung haben. Alle Zeilen, die “Permission denied” sagen, wurden nach stderr geschrieben, und die anderen Zeilen wurden nach stdout geschrieben.
Sie können stderr ausblenden, indem Sie den Dateideskriptor 2 nach /dev/null umleiten, dem speziellen Gerät in Linux, das “nirgendwo hingeht”:
find / -name '*something*' 2>/dev/null
/usr/share/doc/something /usr/share/doc/something/examples/something_random /usr/share/something /usr/games/something
Die an /dev/null gesendeten Fehler werden nicht angezeigt.
Das Verständnis des Unterschieds zwischen stdout und stderr ist wichtig, wenn Sie mit der Ausgabe eines Programms arbeiten möchten. Wenn Sie beispielsweise versuchen, die Ausgabe des find-Befehls zu grep, werden Sie feststellen, dass die Fehlermeldungen nicht gefiltert werden, da nur die Standardausgabe an grep geleitet wird.
find / -name '*something*' | grep 'something'
/usr/share/doc/something /usr/share/doc/something/examples/something_random find: `/run/udisks2': Permission denied find: `/run/wpa_supplicant': Permission denied /usr/share/something /usr/games/something
Sie können jedoch den Standardfehler auf die Standardausgabe umleiten, und dann verarbeitet grep den Text von beiden:
find / -name '*something*' 2>&1 | grep 'something'
/usr/share/doc/something /usr/share/doc/something/examples/something_random /usr/share/something /usr/games/something
Beachten Sie, dass im obigen Befehl dem Zieldateideskriptor (1) ein kaufmännisches Und (“&”) vorangestellt ist. Weitere Informationen zur Datenstromumleitung finden Sie unter Pipelines in der Bash-Shell.
Beispiele für das Erstellen und Verwenden von Dateideskriptoren in Bash finden Sie in unseren Beispielen für exec-integrierte Befehle.
Dateihandle, Betriebssystembedingungen