Expansion on the answer by @sanmai...
And confirmation of what is going on...
#/bin/bash
F=$(mktemp tmp.XXXXXX)
exec 3<>$F # open the temporary file for read and write
rm $F # delete file, though it remains on file system
echo "Hello world!" >&3 # Add a line to a file
cat /dev/fd/3 # Read the whole file
echo "Bye" >>/dev/fd/3 # Append another line
cat /dev/fd/3 # Read the whole file
echo "Goodbye" >&3 # Overwrite second line
cat /dev/fd/3 # Read the whole file
cat <&3 # Try to Rewind (no output)
echo "Cruel World!" >&3 # Still adds a line on end
cat /dev/fd/3 # Read the whole file
shell_seek 3 6 0 # seek fd 3 to position 6
echo -n "Earth" >&3 # Overwrite 'World'
shell_seek 3 # rewind fd 3
cat <&3 # Read the whole file put 3 at end
Note that the echo Goodbye
overwrites the second lineas the file descriptor &3 had not changed by the cat!
So I tried using cat <&3
which did not output anything, probably as the file descriptor was at the end of the file. To see it if it rewinds the descriptor it was given. It does not.
The last part is to use the 'C' program that was provided, compiled and named shell_seek
and yes it seems it works as the first 'World' was replaced by 'Earth', the rewind (seek to start) worked allowing the last cat to again read the whole file. It would put the fd at the end of the file again!
Doing it using perl instead of C was not that hard either.
For example perl -e 'open(FD,">&3"); seek(FD,0,0);'
will rewind file descriptor 3 back to the start of the file.
I have now made a perl version of shell_seek
so I don't have to re-compile it all the time for different systems. Not only that but the script can also 'tell' you the current file descriptor offset, and also 'truncate' the file that file descriptor points too. Both operations are commonly used when using seek, so it seemed a good idea to include those functions. You can download the script from...
https://antofthy.gitlab.io/software/#shell_seek