This question is about reading and writing on a file descriptor. See the following example:#!/bin/shfile='somefile'# open fd 3 rwexec 3<> $file# write something to fd 3printf %s\n%s\n foo bar >&3# reading from fd 3 workscat /proc/$$/fd/3# only works if the printf line is removedcat <&3exit 0This script outputs:foobarExpected output:foobarfoobarOpening and writing to the file descriptor succeeds. So does reading via proc/$$/fd/3. But this is not portable. cat <&3 doesn't output anything. However, it works when the file descriptor is not being written to (e.g. uncomment the printf line).Why doesn't cat <&3 work and how to read the entire contents from a file descriptor portably (POSIX shell)?
Reading from file descriptor fails
file descriptors
cat <&3 does exactly what it's supposed to do, namely read from the file until it reaches the end of the file. When you call it, the file position on the file descriptor is where you last left it, namely, at the end of the file. (There's a single file position, not separate ones for reading and for writing.)cat /proc/$$/fd/3 doesn't do the same thing as cat <&3: it opens the same file on a different descriptor. Since each file descriptor has its own position, and the position is set to 0 when opening a file for reading, this command prints the whole file and doesn't affect the script.If you want to read back what you wrote, you need to either reopen the file or rewind the file descriptor (i.e. set its position to 0). There's no built-in way to do either in a POSIX shell nor in most sh implementations (there is one in ksh93). There is only one utility that can seek: dd, but it can only seek forward. (There are other utilities that may skip forward but that doesn't help.)I think the only portable solution is to remember the file name and open it as many times as necessary. Note that if the file isn't a regular file, you might not be able to seek backwards anyway.