If you ever use pipes and redirections under your Linux shell, chances are you will also sometimes need to make use of the tee
utility.
What Does Tee Do?
A command such as
ls
will display the contents of your current directory. In other words, it displays these contents to stdout (standard output), which is normally your screen, or to be more precise, your virtual terminal display.
A command like
ls > file123
will display nothing on your screen. That’s because the >
sign redirects all output to a file instead of displaying it to stdout. file123 will now be filled with the contents that were previously displayed on your screen.
To display the contents of your directory on the screen and write this to a file, you use two commands. With tee
you can do both of these things at once.
ls | tee file123
Why Use Tee If You Can Run a Similar Command Twice?
In the example above, you obviously don’t need tee if you can execute ls
normally and then execute it again and redirect the output to a file. However, you will encounter situations where the output will be unique. Imagine a scenario where you try to diagnose a problem. You run diagnose | tee error.log
. The errors you get might be unique. You want them displayed on screen so you can see what’s going on as you test things. But you also want those errors saved to a file, so you can review them later or paste the output to a discussion forum and ask people about it.
Another situation, often encountered, when you might need tee, is this: you want to write the output of a command to a location where only the root user can read or write. This won’t work.
/sbin/blkid > /root/somefile
Then, you may think, “Well, of course, just use sudo!” And you will be surprised that this doesn’t work either:
sudo blkid > /root/somefile
That’s because after sudo blkid
executes, you’re still logged in as your regular, non-root user. And your shell (usually bash), tries to write to /root/somefile
with your regular user credentials. To solve this, you can use tee:
/sbin/blkid | sudo tee /root/somefile
Appending Text and Redirecting Errors
tee is a useful but simple command; a basic command | tee somefile
will suffice most of the times. However, there are two scenarios you may encounter that will require these tips.
The first thing to know is that tee, by default, always overwrites a file. If you run
ls | tee somefile
and then
ls /tmp | tee somefile
the second command will overwrite the contents of somefile, and you will only see contents of the last command executed. To change this behavior, you can make tee append text instead of overwrite. To do so, just use the -a
command switch.
ls | tee -a somefile
The second thing to know is that not all output is the same. Error messages are treated differently, and although they appear on screen, they are not considered stdout, so they won’t be caught by tee. (They are considered stderr.) Here’s an example on grep.
grep -r L2TP /etc | tee somefile
It will display something like the following image.
Permission denied messages are written to stderr. The only thing written to stdout is the highlighted text. That’s why you will notice that the contents of “somefile” are what is shown in the below image.
In this case, where grep is used to search for text, it’s useful that error messages aren’t redirected to the file. They would just fill the file with unnecessary garbage. You only want to see the found results. But when you need the error messages, use 2>&1
, which redirects stderr to stdout.
grep -r L2TP /etc 2>&1 | tee somefile
With this command you will notice that somefile now also contains the error messages.
Conclusion
Hopefully, this tutorial covers everything you need to get the most use out of the tee command. But if you encounter a situation where you get stuck with tee, leave a comment below, and we might be able to help.
Our latest tutorials delivered straight to your inbox