19

My env: zsh, macOS


Command in concern:

  1. echo 'hi' | tee > a b c
  2. echo 'hi' > a b c
  • Command 1 creates files named a, b and c with content hi.
  • Command 2 creates a file named a with content hi b c.

AFAIK, only the usage of Command 1 without > is documented in the manpage of tee:

echo 'hi' | tee a b c

I want some help to understand why adding > the above code(i.e., Command 1) still creates multiple files, whereas Command 2 creates only one file.

0

3 Answers 3

50

Redirection (> in this case) “consumes” the following argument as the target of the redirection; everything else is left alone. So

echo 'hi' | tee > a b c

is equivalent to

echo 'hi' | tee b c > a

tee duplicates its input to b, c, and standard output which goes to a.

echo 'hi' > a b c

is equivalent to

echo 'hi' b c > a

and outputs hi b c to standard output, which goes to a.

1
  • 2
    See also echo hi > a > b > c or echo hi > {a,b,c} which does an internal teeing in zsh. Commented Jul 8, 2022 at 14:35
17

This is basic shell syntax. The redirect operator > takes exactly one argument which it uses as a filename to redirect standard output to. The remaining arguments are passed to the command.

So your first command:

echo 'hi' | tee > a b c

runs the command echo 'hi' | tee b c, redirecting its standard output to file a. As it happens, tee copies its standard input to all the files given as arguments, plus its standard output. So the data emitted by echo 'hi' is copied by tee to files b and c, and to its standard output which by redirection is file a.

Your second command:

echo 'hi' > a b c

runs the command echo 'hi' b c, again redirecting its standard output to file a. If you'd care to look at the resulting file a, you'd find it contains the text hi b c whereas in the first case the three created files all contain only the text hi.

12

tee takes the stdin stream and sends a copy to the nominated file(s) and also to stdout. With the > a you are capturing the stdout stream to file a while tee is writing as normal to files b and c.

> filename can appear at any point on its side of the | (as long as it is spaced appropriately and is not escaped).

To illustrate, these are all synonymous:

echo hi | > a tee b c 
echo hi | tee > a b c 
echo hi | tee b > a c 
echo hi | tee b c > a
2
  • 2
    "> filename" can appear at any point on its side of the | (as long as it is spaced appropriately and is not escaped). This line beautifully explains the command execution behavior I didn't understand. Thanks.
    – catwith
    Commented Jul 7, 2022 at 21:36
  • 5
    @catwith to further stress the point, echo > a b c can also be > a echo b c
    – muru
    Commented Jul 8, 2022 at 9:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .