How do redirection in a symbols work in a sequence?

I have file1, file2, file3.


file1 contains 1

file2 contains 2

file3 contains 3

I use command

cat file1 > file2 > file3

Results in:

file1 1

file2 (contains nothing)

file3 1


Why does anything along this line get destroyed? Basically what am I not seeing behind the scenes?

(Side notes using “append” >> is even weirder)

Asked By: No Time

||

When you redirect an fd multiple times, all redirections get performed, and the last one sticks:

$ strace -f -e open bash -c 'cat file1 > file2 > file3'
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
...
[pid 20508] open("file2", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
[pid 20508] open("file3", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
...
[pid 20508] open("file1", O_RDONLY)     = 3

So, file2 was opened and truncated, and then file3 was opened.

Answered By: muru

Redirections in Bourne/POSIX-style shells such as bash, dash, ksh, etc.

processed in the order they appear, from left to right

> x opens and truncates file x, and sets the file descriptor that writes into x as standard output. Your command:

cat file1 > file2 > file3

Will:

  1. Open and truncate file2
  2. Set standard output to write to that file descriptor
  3. Open and truncate file3
  4. Set standard output to write to that file descriptor
  5. Run cat file1

The end result is that standard output points into file3 at the time cat runs. Both file2 and file3 have their current contents erased, and file3 gets the output of cat (the contents of file1) written into it.


If you want to split output into multiple streams written into separate files, you can use tee:

cat file1 | tee file2 > file3

Other shells (notably zsh) behave differently, and your command would have the result you probably expected: both file2 and file3 would have the contents of file1.


Note that cat isn’t necessary here; < input redirection would do the job just as well.

Answered By: Michael Homer
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.