Reputation: 16629
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
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
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