8

Why can it be used only 1 time when we open the file descriptor ourselves and redirect it to stdin? Please take a look at the example below to understand what I want to say. After reading it once with the cat command, the file is not read via the same file descriptor for the second time.

└─$ exec 6< input.txt
└─$ cat <&6
i am just string
and another string..
└─$ cat <&6
└─$

1 Answer 1

14

To print the file, the first cat has to read it until the end. exec 6< input.txt causes the shell to hold the file descriptor until the shell dies or closes it, so the file offset still points to the end of the file when the second cat is invoked, which thus writes nothing to stdout.

If on a Linux-based system, you can see that happening by peeking into the file descriptor info:

echo "File contents" > input.txt
exec 6< input.txt
cat "/proc/$$/fdinfo/6"
cat <&6
cat "/proc/$$/fdinfo/6"
cat <&6

If you execute that script, you will get something like

pos:    0
flags:  0100000
mnt_id: 113
File contents
pos:    14
flags:  0100000
mnt_id: 113

confirming that the offset (pos) is not 0 when the second cat is executed, but instead points to its end.

To reset the offset, you can add another exec 6< input.txt in between the cats.

2
  • 3
    ksh93 and zsh can rewind ksh93 has a exec <#((0)) to rewind. And zsh has sysseek 0 (in the zsh/system module), and you can always execute another command to do the lseek(). Dec 30, 2020 at 13:52
  • 3
    Yes, you can do exec 3<#((0)) or 3>#((0)) like with other redirection operators. Dec 30, 2020 at 16:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .