Post History
Each file descriptor can only point to a single file. File descriptors can be duplicated such that both point to a single file, but a file descriptor cannot point to two files. Hence, you have ...
Answer
#1: Initial revision
Each [file descriptor](https://en.wikipedia.org/wiki/File_descriptor) can only point to a single file. File descriptors can be duplicated such that both point to a single file, but a file descriptor cannot point to two files. Hence, you have to decide whether stdout points to _out.txt_ or to _both.txt_, and similarly with stderr. Of course, you could use [Tee](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/tee.html) to replicate output, since it writes its input directly to files (given as arguments) and to stdout, which you can further redirect. One such approach, proposed in ["How to redirect stderr and stdout to different files and also display in terminal?"](https://unix.stackexchange.com/a/54974), is ((cmd | tee out.txt) 3>&1 1>&2 2>&3 | tee err.txt) &> both.txt It, however, **fails** to preserve the order of stdout and stderr output when writing to _both.txt_. This is because once you send `cmd`'s stdout and stderr to different roads, you can't guarantee that they will take the same time to traverse it. More technically: The two Tees are different, concurrent processes, and as such incur in a [race condition](https://en.wikipedia.org/wiki/Race_condition#In_software); as a result the order of the lines in _both.txt_ is not deterministic. Your proposed trick with Zsh `MULTIOS` also fails to address this issue, since, [as documented](https://zsh.sourceforge.io/Doc/Release/Redirection.html), it does essentially the same thing: > the shell opens the file descriptor as a pipe to a process that copies its input to all the specified outputs, similar to tee, provided the MULTIOS option is set, as it is by default. Unfortunately, although piping both stdout and stderr to another program preserves the line order for _both.txt_, the program then couldn't tell them apart in order to write _out.txt_ and _err.txt_. I.e., in cmd 2>&1 | filter `filter` only has a notion of its stdin; the information of whether this or that line "came from" `cmd`'s stdout or stderr is completely lost. The only reliable and feasible solution I see is to edit the program's source code so as to insert information in its output that shows which lines are stdout and which are stderr (e.g. by prepending "E:" to stderr and "O:" to stdout). Too bad it is cumbersome and not scalable.