Introduction

We may often find ourselves in situations wherein we are running some commands on our Linux/UNIX operating system and we need to display the output of the command to our terminal and save it to a file for future use as well.
The Linux tee command is a utility that is meant to be used for precisely this purpose. We have already provided a quick introduction to the tee command in one of our earlier articles. In this article, we will discuss the different ways in which we could use the tee command in greater detail by means of practical examples. The tee command is part of the coreutils package and therefore should be installed on almost every Linux distribution out there. We’ll be using a Centos 6 machine for demonstrating the examples in this article.

Example 1: Using tee command directly
For our first and basic example, we’ll type the tee command followed by a file name and press enter. From hereon in anything we type on the terminal is redirected back to the terminal in the form of stdout and redirected to the file whose name we specified while invoking the tee command. Here is a demonstration.

[root@linuxnix ~]# tee myfile.txt
this is a basic tee command usage example
this is a basic tee command usage example
[root@linuxnix ~]#
[root@linuxnix ~]# cat myfile.txt
this is a basic tee command usage example
[root@linuxnix ~]#

I typed the tee command followed by a file named myfile.txt. After that my prompt changed and in the current prompt I typed the line ‘this is a basic tee command usage example’ and pressed the enter key. The line I typed was displayed back to me on the terminal after I pressed the enter key. We need to press ctrl+c or ctrl+d key combination to return to our original command line prompt. When I displayed the contents of the file myfile.txt it contained the line that I had typed in earlier when under the tee prompt. This proved that the input we provided to the tee command via the standard input was displayed back to us via the standard output and also redirected to the file we specified with the tee command.

Example 2: Use tee to display output of a command and redirect the output to a file
The previous example was intended to help you understand how the tee command works. We don’t use that form of the tee command in real world situations. The most widely used method of invoking the tee command is by piping the output of a command to it followed by a file name. In this way, the output of the command will serve as input to the tee command and will be displayed onto the terminal via the standard output stream and also redirected to a file which we will specify after the tee command. Given below is an example:

[root@linuxnix ~]# uname -a | tee uname.txt
Linux linuxnix 2.6.32-696.20.1.el6.x86_64 #1 SMP Fri Jan 26 17:51:45 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[root@linuxnix ~]#
[root@linuxnix ~]# cat uname.txt
Linux linuxnix 2.6.32-696.20.1.el6.x86_64 #1 SMP Fri Jan 26 17:51:45 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[root@linuxnix ~]#

In the above example, we typed the ‘uname -a’ command and piped the output of the uname command to the tee command followed by a file named uname.txt. The tee command displayed the output of the uname -a command onto the terminal and redirected it to the file uname.txt.

Example 3: Use tee command to display the output of a command and redirect it to multiple files
Under some circumstances, we may want to keep multiple copies of the output of some commands. This could easily be accomplished with the tee command.  To do use we simply need to specify the destination file named while invoking the tee command. Let’s modify our previous example of redirecting the output of the uname command to a single file and now redirect the output to three files.

[root@linuxnix ~]# uname -a | tee uname.txt uname1.txt uname2.txt
Linux linuxnix 2.6.32-696.20.1.el6.x86_64 #1 SMP Fri Jan 26 17:51:45 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[root@linuxnix ~]#
[root@linuxnix ~]# cat uname.txt ; cat uname1.txt; cat uname2.txt
Linux linuxnix 2.6.32-696.20.1.el6.x86_64 #1 SMP Fri Jan 26 17:51:45 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Linux linuxnix 2.6.32-696.20.1.el6.x86_64 #1 SMP Fri Jan 26 17:51:45 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Linux linuxnix 2.6.32-696.20.1.el6.x86_64 #1 SMP Fri Jan 26 17:51:45 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[root@linuxnix ~]#

Example 4: Use tee command in append mode
The default operation of the tee command will be to override the content of the destination file if it already exists and has some data in it. But this behavior could be modified to append to the destination file instead of overriding it by using the -a option with the tee command. In the below example, we use the file uname.txt from our previous example and store the output of the uptime command as well in the same file by using the tee command in append mode.

[root@linuxnix ~]# uptime | tee -a uname.txt
20:40:49 up 44 min, 2 users, load average: 0.21, 0.15, 0.18
[root@linuxnix ~]#
[root@linuxnix ~]# cat uname.txt
Linux linuxnix 2.6.32-696.20.1.el6.x86_64 #1 SMP Fri Jan 26 17:51:45 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
20:40:49 up 44 min, 2 users, load average: 0.21, 0.15, 0.18
[root@linuxnix ~]#

Example 5: Use tee to write to a file with elevated privileges
You may often attempted to write something to a file using echo and received a permission denied error even though you had elevated privileges using sudo.

[sahil@linuxnix ~]$ id
uid=505(sahil) gid=505(sahil) groups=505(sahil) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[sahil@linuxnix ~]$ ls -l testfile.txt
-rw-r--r--. 1 root root 0 Feb 27 20:44 testfile.txt
[sahil@linuxnix ~]$
[sahil@linuxnix ~]$ sudo echo "This is a test file" > testfile.txt
-bash: testfile.txt: Permission denied
[sahil@linuxnix ~]$

The solution would be to open the file in an editor using sudo and then write the line to the file. We have a workaround for that using the tee command.

[sahil@linuxnix ~]$ echo "This is a test file" | sudo tee -a testfile.txt
This is a test file
[sahil@linuxnix ~]$ cat testfile.txt
This is a test file
[sahil@linuxnix ~]$

In the above example, we were successfully able to write to a file owned by the root account using the echo command and invoking the tee command in append mode with sudo privileges. If you had opened a root owned file for editing using the vi/vim editor, made numerous modifications and got a ‘readonly file’ error while trying to save your changes realizing that you forgot to open the file using sudo, then you would have to open the file again with sudo and edit it. However, you could avoid it using the tee command by typing the following in vi/vim command mode while the file is still open.

:w !sudo tee %

Example 6: Display and redirect real time command output to a file using the tee command
Monitoring application or system logs in real time using the tail command with the -f option is a common practice. Using the tee command we could also redirect these logs to a file while they are being monitored. In the below example, we monitor the /var/log/secure file in real time using the tail command with the -f option and redirect the output to a file named login.log using the tee command.

[root@linuxnix ~]# tail -f /var/log/secure | tee login.log
Feb 27 21:20:04 linuxnix sshd[5816]: Accepted password for root from 192.168.11.1 port 54869 ssh2
Feb 27 21:20:05 linuxnix sshd[5820]: Accepted password for root from 192.168.11.1 port 54871 ssh2
Feb 27 21:20:05 linuxnix sshd[5816]: pam_unix(sshd:session): session opened for user root by (uid=0)
Feb 27 21:20:05 linuxnix sshd[5820]: pam_unix(sshd:session): session opened for user root by (uid=0)
Feb 27 21:20:05 linuxnix sshd[5820]: subsystem request for sftp
Feb 27 21:20:43 linuxnix sudo: root : TTY=pts/1 ; PWD=/root ; USER=root ; COMMAND=/bin/su - sahil
Feb 27 21:20:43 linuxnix su: pam_unix(su-l:session): session opened for user sahil by root(uid=0)
Feb 27 21:20:51 linuxnix su: pam_unix(su-l:session): session closed for user sahil

Example 7: Redirect output using tee while chaining commands
If we chain commands together separated by semicolons and then pipe the outout to the tee command, then we will see the output of all the command on the terminal but only the output of the last command will be redirected to a file. Given below is an example.

[root@linuxnix ~]# uname -a;date;uptime | tee comm.log
Linux linuxnix 2.6.32-696.20.1.el6.x86_64 #1 SMP Fri Jan 26 17:51:45 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Tue Feb 27 21:26:11 IST 2018
21:26:11 up 1:30, 3 users, load average: 0.02, 0.03, 0.02
[root@linuxnix ~]#
[root@linuxnix ~]# cat comm.log
21:26:11 up 1:30, 3 users, load average: 0.02, 0.03, 0.02
[root@linuxnix ~]#

In the above example, we chained three commands together and piped their output to the tee command followed by a file named comm.log. Notice that we could view the output of the three commands on the terminal via the standard output stream but only the output of the last command was recorded in the file. If you wish to redirect and save the output of all the three commands into the file then group the commands using the curly braces {} as shown below.

[root@linuxnix ~]# { uname -a;date;uptime; } | tee comm.log
Linux linuxnix 2.6.32-696.20.1.el6.x86_64 #1 SMP Fri Jan 26 17:51:45 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Tue Feb 27 21:29:27 IST 2018
21:29:27 up 1:33, 3 users, load average: 0.00, 0.01, 0.01
[root@linuxnix ~]# cat comm.log
Linux linuxnix 2.6.32-696.20.1.el6.x86_64 #1 SMP Fri Jan 26 17:51:45 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Tue Feb 27 21:29:27 IST 2018
21:29:27 up 1:33, 3 users, load average: 0.00, 0.01, 0.01
[root@linuxnix ~]#

Conclusion

This concludes our exploration of the tee command. We hope that you’ve found the examples demonstrated in this article to be useful and we look forward towards your feedback.

The following two tabs change content below.

Sahil Suri

He started his career in IT in 2011 as a system administrator. He has since worked with HP-UX, Solaris and Linux operating systems along with exposure to high availability and virtualization solutions. He has a keen interest in shell, Python and Perl scripting and is learning the ropes on AWS cloud, DevOps tools, and methodologies. He enjoys sharing the knowledge he's gained over the years with the rest of the community.