Linux. Bash 4.2.10.
Let's say that i want the stderr of a command redirected to one file (err), and both stdout and stderr redirected to another file (outanderr).
Easy. Many ways to do it. But may times the file outanderr will be messed up (with the output and the error mixed toghether).
See:
lem@biggy:/tmp$ touch imafile
lem@biggy:/tmp$ (ls imafile idontexist 2>&1 >&3 | tee err >&3) 3>outanderr
lem@biggy:/tmp$ cat outanderr
ls: impossibile accedere a idontexist: File o directory non esistente
imafile
It looks nice (sorry for the Italian, but this is so like English that I'm sure it's easily understandable).
But let's retry. After a few times:
lem@biggy:/tmp$ (ls imafile idontexist 2>&1 >&3 | tee err >&3) 3>outanderr
lem@biggy:/tmp$ cat outanderr
ls: impossibile accedere a idontexistimafile
: File o directory non esistente
Here above the output (imafile) has gone in the middle of the error!
Another solution:
lem@biggy:/tmp$ ((ls imafile idontexist >&3) 2> >(tee err >&4)) 3>outanderr 4>&3
lem@biggy:/tmp$ cat outanderr
ls: impossibile accedere a idontexist: File o directory non esistente
imafile
Nice. Let's retry. After a few times:
lem@biggy:/tmp$ ((ls imafile idontexist >&3) 2> >(tee err >&4)) 3>outanderr 4>&3
lem@biggy:/tmp$ cat outanderr
ls: impossibile accedere a idontexistimafile
directory non esistente
Again: output in the middle of the (semi-cutted) error.
The same with things like:
$ ls imafile idontexist >outanderr 2> >(tee err >>outanderr)
The only one I've found to be safe in my shell seems to be:
$ ls imafile idontexist 2> >(tee err >outanderr) | tee -a outanderr >/dev/null
So, my questions are:
a) what's going on?
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?
c) the last solution is really safe? If so, why?
Thanks for everything.
--
Bye