qdo
qdo

Reputation: 92

File output was overwritten using tee within Bash Shell script

I was trying to learn how exec and tee work and encountered something I could not understand:

# create a log.out file in current directory
log=$(echo $(pwd)/log.out)

# start redirect
# 3 holds stdout, 4 holds stderr
# 1 & 2 points to log.out
exec 3>&1 4>&2 &>${log}

# print 'Have a good day everyone!' to both log.out and stdout 
echo 'Have a good day everyone!' | tee ${log} 1>&3
echo 'Ciao!'
echo 'Bye!'

# end redirect
exec 1>&3 2>&4 3>&- 4>&-

When I went into log.out file, I got this:

Ciao!                                                                                                                                                 
Bye!                                                                                                                                                  
 day everyone!

I was expecting:

Have a good day everyone!
Ciao!
Bye!

Please help me understand what is going on here and how to resolve this.

Thank you.

If this is duplicate, please close and give me the link to the solution.

Upvotes: 0

Views: 555

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295815

What's happening here is that while tee is adding content to your file, the existing open file pointer created by exec &>log.out is still back at the beginning of that file. Thus, when you start writing to that file pointer, those writes start at the beginning, despite other contents having been written by tee.


If you want to ensure that content is always added to the end of the file, even if other software has modified where that end-of-the-file location is, then you should ensure that the O_APPEND flag is used on open.

To do this, use >> rather than > for your redirection:

exec 3>&1 4>&2 &>>${log}

Upvotes: 3

Related Questions