Unterschied zwischen Datei und mit einer Datei verknüpftem Dateideskriptor

Unterschied zwischen Datei und mit einer Datei verknüpftem Dateideskriptor

Ich habe eine Datei, die vier Zeilen enthält:

$ cat file
First line
Second line
Third line
Fourth line
$ 

Wenn ich diese Datei viermal lese, lese ich immer die erste Zeile, was ein erwartetes Ergebnis ist:

$ for i in {1..4}; do read line <file; echo "$line" ; done
First line
First line
First line
First line
$ 

Wenn ich jedoch den Dateideskriptor 3 verknüpfe fileund ihn dann auf die gleiche Weise lese, dann „frisst“ jeder Lesevorgang den Eingabestrom:

$ exec 3<file
$ for i in {1..4}; do read -u 3 line; echo "$line" ; done
First line
Second line
Third line
Fourth line
$

Warum verhalten sich Dateideskriptoren so?

Antwort1

Wenn Sie sagen: read var <fileDer Dateideskriptor wird geschlossen, sobald der Befehl beendet ist. Daher wird der Dateideskriptor beim nächsten Mal in der Schleife auf den Anfang zurückgesetzt.

Im Fall von exec 3<file, wenn Sie sagen, read -r -u 3 vardass der Dateideskriptor geöffnet bleibt, auch wenn der Lesebefehl beendet ist UND die Leseposition aktualisiert wird, sodass beim nächsten Mal beim Lesen die nächste Zeile erfasst wird.

Hinweis: Auch wenn Sie dies getan hätten, würde es sich trotzdem ähnlich verhalten exec 0<file.read -r var

Antwort2

Die kurze Antwort lautet, dass sie so konzipiert sind: Ein Dateideskriptor enthält einen Status, der eine Lese- und eine Schreibposition umfasst. Jeder Lesevorgang, der an einem Dateideskriptor ausgeführt wird, verschiebt die Leseposition, unabhängig davon, wer daraus liest – der Dateideskriptor enthält nur eine Leseposition.

Auf andere Weise wird beim Erstellen eines Dateideskriptors (durch das Betriebssystem) auch eine Struktur/Tabelle erstellt, die diese Statusvariablen enthält. Es gibt nur eine Kopie der Leseposition in der Tabelle, und jedes Mal, wenn die Funktion read() für den Dateideskriptor aufgerufen wird, wird die einzelne Lesepositionsvariable aktualisiert.

verwandte Informationen