Shell – Difference between file and file descriptor linked to a file

file-descriptorsshell

I have a file which contains four lines:

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

When I read this file four times, then I always read the first line which is an expected result:

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

However, when I link file descriptor 3 with file and then read it in the same fashion, then each read "eats" the input stream:

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

Why do file descriptors behave like this?

Best Answer

When you say: read var <file the file-descriptor is closed once the command finishes. Hence, the next time around in the loop, the file-descriptor is reset to the beginning.

In the case of exec 3<file, when you say read -r -u 3 var the file descriptor stays open even when the read command finishes AND the read position is updated so the next time around, the read will grab the next line.

Note: Even if you had done, exec 0<file and then read -r var it will still behave similarly.

Related Question