Разница между файлом и файловым дескриптором, связанным с файлом

Разница между файлом и файловым дескриптором, связанным с файлом

У меня есть файл, содержащий четыре строки:

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

Когда я читаю этот файл четыре раза, я всегда читаю первую строку, что является ожидаемым результатом:

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

Однако когда я связываю файловый дескриптор 3 с fileи затем читаю его таким же образом, то каждое чтение «съедает» входной поток:

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

Почему дескрипторы файлов ведут себя таким образом?

решение1

Когда вы говорите: read var <fileдескриптор файла закрывается после завершения команды. Следовательно, в следующий раз в цикле дескриптор файла сбрасывается в начало.

В случае exec 3<file, когда вы говорите, read -r -u 3 varчто дескриптор файла остается открытым даже после завершения команды чтения И позиция чтения обновляется, поэтому в следующий раз чтение захватит следующую строку.

Примечание: Даже если вы это сделали, то exec 0<fileи тогда read -r varон все равно будет вести себя аналогично.

решение2

Быстрый ответ заключается в том, что они так и задуманы — файловый дескриптор содержит состояние, которое включает позицию чтения и записи. Каждое чтение, выполненное на одном файловом дескрипторе, перемещает позицию чтения, независимо от того, кто читает из него — файловый дескриптор содержит только одну позицию чтения.

Другим способом, когда создается дескриптор файла (ОС), он также создает структуру/таблицу, содержащую эти переменные состояния. В таблице есть только одна копия позиции чтения, и каждый раз, когда функция read() вызывается для дескриптора файла, обновляется единственная переменная позиции чтения.

Связанный контент