I found a magic command here./my.sh 3>all 1> >(tee out >&3) 2> >(tee err >&3)I am confused at some places:Does 3>all mean setting the file descriptor 3 for file all?What do 1> > and 2> >? As per my understanding, the command should be ./my.sh 3>all 1>(tee out >&3) 2>(tee err >&3). But that doesn't work.Why doesn't (tee err >&3) overwrite the file all?This is my my.sh#!/bin/bashecho myechols dflj
Uunderstanding the redirections in this command?
io redirection;syntax
You can read about this syntax in the bash man page under Process substitution:>(list).  The process list is run with its output connected to some file  in /dev/fd.  The name of this file         is  passed  as  an argument to the current command as the result of the         expansion. Look at the output of this command which does not do any redirection:echo >(echo hi >/tmp/a) >(echo lo >/tmp/b)it is (on my system):/dev/fd/63 /dev/fd/62So you must read 1> >(...) as 1> and >(...). The second part gets replaced by /dev/fd/63, and we then have 1> /dev/fd/63 so we redirect stdout to file descriptor 63.  bash runs the command inside >(...) in a separate process, and connects the stdin of that process to file descriptor 63.  Check out this example:set -xecho hello > >(cat -n)The stdout of the echo is piped into the input of cat -n and you get:+ echo hello++ cat -n 1  helloPerhaps what you are missing is that when you have a file descriptor (fd) for a file, and then fork the process (which bash is doing with >(...)), you can inherit the same fd in the new process. So the 2 processes share the same fd. Moreover, there is only one file offset for an fd, so if process 1 writes 3 characters to the fd, then the offset moves from 0 to 3. If process 2 then writes 5 characters to the fd, the data is placed at offset 3 and the offset becomes 8. If process 1 writes another character it is placed at offset 8, and so on. This is how the two tee commands in your question manage to write to the same file all without overwriting each other.Using >&3 does not create a new fd; it simply closes the current stdout fd 1, then renumbers fd 3 to fd 1. So there is still only one fd for the two processes, even if the number now seen by each process is different (see man dup2 for the underlying system call).