The Coreutils tee Command

We have already seen how to redirect content to stdout and into files. The tee command provides an extra layer of flexibility, taking input from stdin then redirecting that stream to both stdout and the specified file. This can be very handy in a few cases, such as when debugging pipelines, as it provides a way to "instrument" the pipeline to gain visibility into intermediate content.

The tee command has the call signature:

{ previous command } | tee {filename} | { next command }

Where previous command represents any command that redirects its output to stdin, and next command represents any command that accepts input on stdin.

Lets extend out previous example to see how the tee command works. First, let's start with the simple echo command we saw earlier:

·
·
·
·
·
·
·
ninja$:·echo·Hello·World!
Hello·World!
ninja$:··

As a brief recap, the echo command simply passes its string argument to stdout, which is exactly what we need to get some simple content to pipe to the tee command. Now, let's implement the pipe and see what happens:

·
·
·
·
·
·
·
ninja$:·echo·Hello·World!·|·tee·test.txt
Hello·World!
ninja$:··

The output is identical to that of the echo command, meaning that the content passed to stdin was simply redirected to stdout, which is what we expected. However, test.txt now contains the same content:

Hello World!

which demonstrates the basic functionality of the tee command; content piped to stdin get redirected to both stdout and the specified file (test.txt in this example).

Let's now take a quick look at using the tee command's --append (or -a) option. When --append is passed to the tee command then the output is appended to the specified file, rather than overwriting the file (the default behavior). This can be useful when debugging pipelines since each value passed through the pipeline will be retained in the output file for inspection.

Repeating the previous command with the --append option writes the same content to stdout:

·
·
·
·
·
·
·
ninja$:·echo·Hello·World!·|·tee·--append·test.txt
Hello·World!
ninja$:··

while inspecting test.txt indicates that the content of the second call did in fact append to the file, as expected:

Hello World!

Hello World!