Quote:
So, my questions are:
a) what's going on?
Multiple processes are writing to the same file. Some of the streams are unbuffered (stderr) and some are buffered (stdout). You are at the mercies of the c library's stream buffering and the system scheduler.
(ls imafile idontexist 2>&1 >&3 | tee err >&3) 3>outanderr:
1. ls writes 'imafile' to its stdout stream (outanderr file). This stream is fully-buffered so the word just sits in a buffer.
2. ls writes the "idontexist" error message to the stderr stream (the pipe). This is an unbuffered stream, so the c library executes the system call to write the error message to the pipe.
3. ls is done, so all of its buffers are flushed and it exits. This prints the word "imafile" which had been buffered.
Initially, tee is sleeping, since there's nothing in the pipe. Once ls writes that error message, the system knows that it can wake tee. In your examples, tee is always woken before ls can flush "imafile" (between steps 2 and 3 above). The mixing of the streams occurs when tee isn't able to finish writing the entire message to its stdout before ls resumes at step 3.
Quote:
b) since all redirections are set before executing the commands, where's the difference with a simple thing as $ ls imafile idontexist >outanderr 2>&1, which never ever fails?
There is only one process involved.
Quote:
c) the last solution is really safe? If so, why?
No.
ls imafile idontexist 2> >(tee err >outanderr) | tee -a outanderr >/dev/null is not immune.
Regards,
Alister