Nehal J Wani
Nehal J Wani

Reputation: 16629

Redirecting Multiple stdouts

I have three files ina a directory named One, Two, Three.

One contains:

asdfg

Two contains:

qwerty

Three contains:

zxcvb

When I give the following command:

$ls > One > Two > Three

Then I give the following command:

$cat One

Output:

Nothing

Then I give the following command:

$cat Two

Output:

Nothing

Then I give the following command:

$cat Three

Output:

One
Three
Two

Can anyone please shed light on what exaclty is happening here? Why do the files One & Two become empty and the why does the output of the ls command get written only to the file Three?

Upvotes: 3

Views: 135

Answers (2)

Thor
Thor

Reputation: 47089

As mentioned here bash doesn't support demultiplexing, and it doesn't support multiplexing either. The effect that you're seeing is that each file is opened O_TRUNC, which means all content is destroyed. When multiple redirections are specified they're closed again right away, only the last redirection is kept and actually receives any data.

Here's an excerpt of strace running the command:

strace -f -e open,dup2,close bash -c 'ls > one > two > three'
...
open("one", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
dup2(3, 1)                  = 1
close(3)                    = 0
open("two", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
dup2(3, 1)                  = 1
close(3)                    = 0
open("three", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
dup2(3, 1)                  = 1
close(3)                    = 0
...

As you can see bash keeps overwriting the same file descriptor. so only the last one will receive any data. One work around is to use tee which writes what it receives on stdin to all its arguments and stdout:

ls | tee One Two Three > /dev/null 

On a side note, zsh does support this:

 zsh$ setopt multios
 zsh$ ls > One > Two > Three

Upvotes: 3

tripleee
tripleee

Reputation: 189317

You can only redirect once. The first redirect opens the first file for writing (removing any previous contents), then closes it immediately when the next redirect overrides it.

You seem to be looking for the tee command.

Upvotes: 2

Related Questions