1

I had to use the following command in an assignment:

who|tee test|wc -l

The output on my system is below, which implies that 2 users are connected:

2

Why is it I don't get the output of who on the screen, and right after that the output of wc -l? I thought tee wrote the output to the screen and created a file with the same output at the same time?

The output of who is however found in my file "test", but still it doesn't make sense to me.

2

The effect of piping to tee is that whatever your first command writes to its standard output is written to a file (whose name you passed as a command-line argument to tee) as well as written to the standard output of the tee command. If the pipeline doesn't continue and you don't perform any redirections on the tee command, then tee's standard output is that of your shell, usually your terminal.

That's why running who and running who | tee test show the same text on your terminal. The difference with tee you also write it to a file.

If the pipeline continues, as with who | tee test | wc -l, then whatever standard output would have been written to the terminal is sent to the next command in the pipeline instead. This is the wc command and, unlike tee, wc does not copy its input to standard output (or anywhere). Instead it shows statistics. With the -l option it shows just line counts, so that's all you see.

So the reason you see just 2 from who | tee test | wc -l is the same as the reason you see just 2 from who | wc -l. The tee command writes the output of who to a file but it does not cause it to be printed to the terminal unless its standard output is the terminal. By default it usually is, but not when you pipe it to yet another command.

If you've seen a command on the left side of a | whose output is displayed on the terminal rather than being used as input to the next command in the pipeline, then it likely was writing to standard error instead of standard output.

1

tee duplicates input so it goes to the file and stdout. From there stdout is piped to wc...it becomes stdin for wc. wc just returns counts, the input data it counts isn't echoed.

If you're trying to make sense of it you could think of cmd1 | tee file | cmd2 as having the same effect as this:

cmd1 > file
cat file | cmd2

This isn't what actually happens but from the standpoint of the person executing the command they would appear to be the same (as long as cmd1 is fast enough to give the impression that everything happens almost simultaneously). In reality file is being filled with data at the same time that cmd2 is receiving that data.

0

To see both who and wc outputs in bash do:

who | tee >(wc -l) test

Output:

me       tty7         2017-10-16 18:17 (:0)
1

Along with the contents of test.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.