I am trying to output tee while writing to a custom file descriptor. Example:
exec 4>"/tmp/testfile.txt"; # open FD 4 tee -a >&4 <<< "Output this to stdout" # Write to open file exec 4>&- # close FD
If I perform instead
tee -a /proc/self/fd/4 <<< "Output this to stdout" I can see the output in my terminal / standard stdout.
I am using BASH 5.0.16(1)-release.
I tried doing a connection between FD 1 (stdout) and FD 4 but then my string wouldn´t be written to the file.
Thanks a lot!
EDIT: Please refer to @Stéphane Chazelas answer. My updates below may be true but way to complicated.
I am getting closer I guess.
tee <<< "Output this to stdout" >(tee -a >&4) I can actually see the output in my terminal and it writes to the file but for some reason it overrides the content and doesn´t seem to append (-a).
Update 2: I feel like I´ve found my mistake now.
First: Using Bash Process Substitution I was able to output to stdout and write to my FD by using tee two times. I did this in this way:
exec 4>"/tmp/testfile.txt"; # open FD 4 tee >(tee -a >&4) <<< "Output this to stdout" # Write to open file exec 4>&- # close FD
As mentioned before the file content is overwritten which is the second part of the answer.
Second: I´ve totally forgot about seek positions! If I open a file using
exec 4>"..." the seek position (or pointer) is at the beginning of the file. In this case appending is like overwritting the file.
To fix this the file descriptor needs to read the complete file before any action to set the current position to the end of the file. One solution is just using
cat. Of course I also need to open the file for reading then (<>).
Finally: This works for me. It opens a FD for a file, read it´s content and append to it.
exec 4<>"/tmp/testfile.txt"; # open FD 4 read (<) and write (>) cat <&4 >/dev/null; tee >(tee -a >&4) <<< "Output this to stdout" # read fd (>/dev/null to silent the output) for correct position and append to. Also output to stdout exec 4>&- # close FD (this closes it completly, so no need for exec 4<&-)
KEEP IN MIND: This can actually be carefull if you use multiple processes which modify the file. If I read correctly it´s not a "true" append. Example: You did a cat and the position is 3. Someone else appends to the file two lines in the meantime. If you now append using your current known position the other two lines are lost.
I guess I´ve learned a bit about file reading in Unix systems again. Overall I might need to overthink my idea of opening a FD. If you know the file will be empty you are fine. But it can be risky with files which have already content and esp. when another process may write to it when your pointer is not up to date. I may explained some technical aspects wrong but it should be correct in some way.