Softpanorama

May the source be with you, but remember the KISS principle ;-)
Home Switchboard Unix Administration Red Hat TCP/IP Networks Neoliberalism Toxic Managers
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and  bastardization of classic Unix

tee command

News Classic Unix Tools Unix Unilities Recommended Links Options Examples Shells Unix script command
Pipes Pipes in Loops Shell Input and Output Redirection Process Substitution in Shell script AWK xargs pv
find grep sort cut uniq Exit Status Etc

Tee is a very important Unix command as it permit construction of complex pipes. The idea is to split pipe so that you write to the standard output (most commonly the next stage of the pipe) and to a file (or named pipe) simultaneously. There is a special version of tee to document terminal sessions called script

Tee is also very useful in complex pipes debugging: you place the tee command anywhere in a pipe command to divert a copy of the standard input (of tee) to disk and give possibility to analyze correctness of this stage. There is more specialized command for this purpose called pv (pipe viewer) but it is available not in all distributions and is rare outside Linux. Another, more specialized variant of the tee functionality is provided by script which permits duplicating all input and output of commands on the text terminal. Few know about script functionality which is useful not only for logging of terminal session (which is screen main usage) but also for communication between different users.

The name tee is also very apt: it is taken from the world of plumbing and perfectly describes the purpose.

The typical usage is to split some stage of a complex pipe diverting output for different processing or debugging or as backup (if stage takes a long time). Diverting output to a names pipe is that only way non-linear pipes can be implemented in Unix. So it is very important to understand that the target in tee can be not only file but a named pipe.

A typical example of tee usage would be

sort somefile.txt | tee sorted_file.txt | uniq -c |  head 12 > top12.txt

More complex example would be processing records of proxy usage that contain code 403 to extract champions, top 12 users who got the most of rejections:

# gzip -d -c all_code403.gz | cut -d ' ' -f 1 | sort -k 1 | uniq -c | sort -r \
| tee ./d$1/all_users | head -12 > ./d$1/all_champs 

Here we first write all the users sorted in reverse order to the disk and then generated the top 12 using head. In this case standard output of tee is piped to head

You can use the tee command to debug complex pipes that for some reason do not work as expected. It can be placed anywhere in a pipe to check what the output looks like at a certain point. you can also save some pipes stages output for future usage if it represents the result of the stage that takes a lot of time. Such situation often arise of you process proxy or HTTP server logs using pies.

The other interesting usage of tee is to split pipe into several substreams using named pipes, for example

mkfifo pipe1 pipe2 # create named pipes
echo ***
gzip -d -c all$1.gz | tee pipe1 | grep '" 200' | tee pipe2 >(gzip > all$1ok.gz) | cut -d '"' -f 2 | cut -d '/' -f 3 | tr '[:upper:]' '[:lower:]' | sort | uniq -c | sort -r > ./d$1/oksites$1 & \
<pipe1 cut -d ' ' -f 1 | grep '" 403 ' | sort | uniq -c | sort -r > ./d$1/all$1xuser & \
<pipe2 cut -d ' ' -f 1 | sort | uniq -c | sort -r | tee ./d$1/all$1users | head -12 > ./d$1/all$1champ

Syntax

Following is the general format of the tee command.

     tee [ -ai ] file_list

Options

The following options may be used to control how tee functions.

-a Appends the output to an existing file. If the file does not exist it will be created. Normally an existing file would be overwritten.
-i Ignore interrupts. If you press the Delete key, tee ignores the interrupt signal sent to it and continues processing.

Arguments

file_list -- One or more files where tee writes copies of the input.

Examples

Using the tee command to save stdout to tee.txt. stdout is still displayed on the screen.
cmd | tee tee.txt
Using the tee command to append stdout to tee.txt. stdout is still displayed on the screen.
cmd | tee -a tee.txt

Extracting users from etc passwd and printing them and displaying on the sceeen simultaniouly:

awk -F: '{ print $1}' /etc/passwd | sort | tee users | lp

Notice the message returned by lp. You now have a printout on the default printer. The output is also stored in the file named users.

The following command copies stdout and stderr to the files "stdout.txt" and "stderr.txt", respectively.
(((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3\
   | tee stderr.txt) 3>&1 1>&2 2>&3) 1>out.txt 2>err.txt

This is pretty exotic example of capturing stderr with tee by swapping stderr and stdout taken verbatum from Linux I-O Redirection)

The full command
(((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 \
     | tee stderr.txt) 3>&1 1>&2 2>&3) 1>out.txt 2>err.txt 
The walk through <
  1. Contents of the ./cmd script
    #!/bin/sh
    #You can use this sample script for testing.  The echo
    #    statements explain how this script works.
    echo "This is Standard Out" >&1
    echo "This is Standard Error" >&2
  2. Results from running the ./cmd script
    ./cmd 
    This is Standard Out
    This is Standard Error
    #
    Although you see both lines printed on the screen, behind the scenes one actually went to stdout and the other went to stderr. If you were to do a pipe, only stdout goes through the pipe. Normally this is the desired effect.

  3. Capturing stdout

    The following will capture a copy of stdout and save it to a file called "stdout.txt"

    ./cmd | tee stdout.txt
    
    stdout goes through the pipe and tee is able to save a copy of it to the file "stdout.txt"; however, we just lost control of stderr. stderr will not go through the pipe, instead it goes directly to our display.
  4. Gaining control of stderr and stdout.

    Lets gain control again of stderr and stdout. We do this by surrounding our command with a set of parenthesis.
    (./cmd | tee stdout.txt) 
    
  5. Swapping stdout and stderr.

    Now that we have captured stdout, we wish to capture stderr using tee as well. The pipe will only accept stdout, so we must swap stderr and stdout to do this.

    Note: The switch is using the standard variable switch method -- 3 variables (buckets) are required to swap 2 variables with each other. (you have 2 variables and you need to switch the contents - you must bring in a 3rd temporary variable to hold the contents of one value so you can properly swap them).

    (./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 
    
  6. Capturing stderr

    Now that we have swapped our stdout and stderr, lets hook up tee once again. tee will now capture stderr (tee believes that it is really stdout because stdout is the only thing that can come through the pipe).
    (./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 \
    | tee stderr.txt
  7. Gaining control of stderr and stdout, for the 2nd time.

    Tee grabs stderr, but once again the channel that doesn't go through the pipe gets sent to the display and we loose it. Lets capture both our stderr and stdout, once again, by using parenthesis.
    ((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 \
    | tee stderr.txt) 
    
  8. Swapping stdout and stderr back to their normal state.

    Now we have, once again, captured both stderr and stdout for our use. Currently they are reversed. Lets switch them back for proper use in our pipeline. Again, lets use the standard variable switch to swap them around.
    ((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 \
    | tee stderr.txt) 3>&1 1>&2 2>&3
  9. Gaining control of stderr and stdout, for the 3rd time.

    At this point we have swapped stdout and stderr back to their normal positions; however, if we will be manipulating stdout and stderr any further, we should complete this command with either a pipe or another set of parenthesis.

    Since we want to be as complete as possible in this example we will use parenthesis. Using parenthesis will gain control over both stdout and stderr. Using a pipe will only gain control over stdout.

    Note: If we use a pipe or parenthesis the next process that hooks up to this command will see stderr and stdout in their proper place. If we don't add the last set of parenthesis, or go through a pipe, the order will remain messed up.
    (((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 \
    | tee stderr.txt) 3>&1 1>&2 2>&3) 
    
  10. Redirecting stdout and stderr to separate files

    Now lets do something productive with stdout and stderr so that we can really prove that everything went back to their proper place. Lets tell our command to redirect stdout to "out" and stderr to "err".
    (((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 \
    | tee stderr.txt) 3>&1 1>&2 2>&3) 1>out.txt 2>err.txt 
    Note: This last step is optional, normally you would insert your other required commands here, commands that would more than likely operate on stdout.

    Please note that the results for "out" and "err" are the same as when you run the following command. This proves that we restored stdout and stderr back to their normal usable posisitions. The above command; however, gives us the capability to copy out stdout and stderr using tee and still be able to use stdout and stderr like we always have.
    ./cmd 1>out.txt 2>err.txt 

Capturing stderr in one file and stderr and stdout combined in another file

I had a request for stderr in 1 file and stderr and stdout combined in another file so here it is:
Here is our testing command we will use to generate both stderr 
and stdout on proper channels:
root@server:~> (echo out >&1; echo err >&2)
out
err
And here is the command to do the work:
root@server:~> (((echo out >&1; echo err >&2) 3>&2 2>&1 1>&3 | \
tee stderr.txt ) 3>&2 2>&1 1>&3 ) > combined.txt 2>&1
root@server:~> cat stderr.txt
err
root@server:~> cat combined.txt
out
err
root@server:~>
Please keep in mind when reading a book or web page with command line documentation
that the trailing slash signifies continuation of the current line. The reason for
this is due to the line width available on the screen and printed page. Note that
the trailing slash must be the last character on the line followed by enter. Spaces,
tabs, etc., may not apear after the trailing backslash because that does not signify
line continuation but rather some form of escape character. There are two ways that
you may enter this information at the command line:

1. Exactly as show, with the backslashes, followed by enter marks or

(((echo out >&1; echo err >&2) 3>&2 2>&1 1>&3 \
| tee stderr.txt ) 3>&2 2>&1 1>&3 ) > combined.txt 2>&1

2. Remove the trailing backslashes and do not press enter after each line, just word wrap
the lines together at the command prompt.

(((echo out >&1; echo err >&2) 3>&2 2>&1 1>&3 | tee stderr.txt ) 3>&2 2>&1 1>&3 ) > combined.txt 2>&1

Tricks UrFix's Blog Page 3

1) Save a file you edited in vim without the needed permissions
:w !sudo tee %

I often forget to sudo before editing a file I don’t have write permissions on. When you come to save that file and get the infamous “E212: Can’t open file for writing”, just issue that vim command in order to save the file without the need to save it to a temp file and then copy it back again.

2) Use tee to process a pipe with two or more processes
echo "tee can split a pipe in two" | tee >(rev) >(tr ‘ ‘ ‘_’)

Tee can be used to split a pipe into multiple streams for one or more process to work it. You can add more ” >()” for even more fun.

3) Duplicate several drives concurrently
dd if=/dev/sda | tee >(dd of=/dev/sdb) | dd of=/dev/sdc
If you have some drive imaging to do, you can boot into any liveCD and use a commodity machine. The drives will be written in parallel.

To improve efficiency, specify a larger block size in dd:

dd if=/dev/sda bs=64k | tee >(dd of=/dev/sdb bs=64k) | dd of=/dev/sdc bs=64kTo image more drives , insert them as additional arguments to tee:

dd if=/dev/sda | tee >(dd of=/dev/sdb) >(dd of=/dev/sdc) >(dd of=/dev/sdd) | dd of=/dev/sde

4) Save a file you edited in vim without the needed permissions (no echo)

:w !sudo tee > /dev/null %
Write a file you edited in Vim but that you do not have the permissions to write to (unless you use sudo.) Same as #1204 but without the echo to stdout that I find annoying.

5) run command on a group of nodes in parallel

echo “uptime” | tee >(ssh host1) >(ssh host2) >(ssh host3)

6) tee to a file descriptor

tee >(cat – >&2)

the tee command does fine with file names, but not so much with file descriptors, such as &2 (stderr). This uses process redirection to tee to the specified descriptor.

In the sample output, it’s being used to tee to stderr, which is connected with the terminal, and to wc -l, which is also outputting to the terminal. The result is the output of bash –version followed by the linecount

7) Add a line to a file using sudo

echo “foo bar” | sudo tee -a /path/to/some/file

This is the solution to the common mistake made by sudo newbies, since

sudo echo "foo bar" >> /path/to/some/filedoes NOT add to the file as root.

Alternatively,

sudo echo "foo bar" > /path/to/some/fileshould be replaced by

echo "foo bar" | sudo tee /path/to/some/fileAnd you can add a >/dev/null in the end if you’re not interested in the tee stdout :

echo "foo bar" | sudo tee -a /path/to/some/file >/dev/null

8) Save a file you edited in vim without the needed permissions – (Open)solaris version with RBAC

:w !pfexec tee %

9) bash or tcsh redirect both to stdout and to a file

echo “Hello World.” | tee -a hello.txt

When plumbers use pipes, they sometimes need a T-joint. The Unix equivalent to this is ‘tee’. The -a flag tells ‘tee’ to append to the file, rather than clobbering it.

Tested on bash and tcsh.

10) Run a bash script in debug mode, show output and save it on a file

bash -x test.sh 2>&1 | tee out.test

Sends both stdout and stderr to the pipe which captures the data in the file ‘out.test’ and sends to stdout of tee (likely /dev/tty unless redirected). Works on Bourne, Korn and Bash shells.

11) Both view and pipe the file without saving to disk

cat /path/to/some/file.txt | tee /dev/pts/0 | wc -l

This is a cool trick to view the contents of the file on /dev/pts/0 (or whatever terminal you’re using), and also send the contents of that file to another program by way of an unnamed pipe. All the while, you’ve not bothered saving any extra data to disk, like you might be tempted to do with sed or grep to filter output.

12) Insert text at the end of a root-privileged file

echo “text” | sudo tee -a /path/file.conf > /dev/null

You can add repositories, options etc to any .conf in your system!


Top Visited
Switchboard
Latest
Past week
Past month

NEWS CONTENTS

Old News

[Jun 08, 2021] How to use TEE command in Linux

Apr 21, 2021 | linuxtechlab.com

3- Write output to multiple files

With tee command, we have option to copy the output to multiple files as well & this can be done as follows,

# free -m | tee output1.txt output2.txt

... ... ...

5- Ignore any interrupts

There are instances where we might face some interruptions while running a command but we can suppress that with the help of '-i' option,

# ping -c 3 | tee -i output1.txt

[Apr 22, 2021] How to use TEE command in Linux

Apr 22, 2021 | linuxtechlab.com

3- Write output to multiple files

With tee command, we have option to copy the output to multiple files as well & this can be done as follows,

# free -m | tee output1.txt output2.txt

... ... ...

5- Ignore any interrupts

There are instances where we might face some interruptions while running a command but we can suppress that with the help of '-i' option,

# ping -c 3 | tee -i output1.txt

[Jun 17, 2019] How to use tee command in Linux by Fahmida Yesmin

Several examples. Mostly trivial. But a couple are interesting.
Notable quotes:
"... `tee` command can be used to store the output of any command into more than one files. ..."
"... `tee` command with '-i' option is used in this example to ignore any interrupt at the time of command execution. ..."
Jun 17, 2019 | linuxhint.com

Example-3: Writing the output into multiple files

`tee` command can be used to store the output of any command into more than one files. You have to write the file names with space to do this task. Run the following commands to store the output of `date` command into two files, output1.txt, and output2.txt.

$ date | tee output1.txt output2.txt
$ cat output1.txt output2.txt

... ... ...

Example-4: Ignoring interrupt signal

`tee` command with '-i' option is used in this example to ignore any interrupt at the time of command execution. So, the command will execute properly even the user presses CTRL+C. Run the following commands from the terminal and check the output.

$ wc -l output.txt | tee -i output3.txt
$ cat output.txt
$ cat output3.txt

... ... ...

Example-5: Passing `tee` command output into another command

The output of the `tee` command can be passed to another command by using the pipe. In this example, the first command output is passed to `tee` command and the output of `tee` command is passed to another command. Run the following commands from the terminal.

$ ls | tee output4.txt | wc -lcw
$ ls
$ cat output4.txt

Output:
... ... ...

[Jun 19, 2014] Everything about GNU-Linux and Open source Linux Terminal the tee command

Linuxaria

2) Save a file as root with your normal user

Sometimes you start to edit a file without noticing that you can't save it for permissions problems, tee can easily save you in this case, as example:

$ vim /etc/passwd
[:w !sudo tee %]

In vim this means:

:w saves the file
!sudo calls the sudo command
tee redirects vim's output
% the current file

After this command you'll have saved successfully your file and can exit safely from the editor.

3) Duplicate several drives concurrently

dd if=/dev/sda | tee &gt;(dd of=/dev/sdb) | dd of=/dev/sdc

If you have some drive imaging to do, you can boot into any liveCD and use a commodity machine. The drives will be written in parallel.

To improve efficiency, specify a larger block size in dd:

dd if=/dev/sda bs=64k | tee &gt;(dd of=/dev/sdb bs=64k) | dd of=/dev/sdc bs=64k

To image more drives , insert them as additional arguments to tee:

dd if=/dev/sda | tee &gt;(dd of=/dev/sdb) &gt;(dd of=/dev/sdc) &gt;(dd of=/dev/sdd) | dd of=/dev/sde

5) Run a command on a group of nodes in parallel via ssh

There are a lot of tools and utility to give the same command on multiple nodes, a really simple way is this one:

echo "uptime" | tee &gt;(ssh host1) &gt;(ssh host2) &gt;(ssh host3)

6) Simple terminal redirection with script and tee

Using the script command you can
display the commands and their output to another user who is connected to another terminal, by example pts/3

script /dev/null | tee /dev/pts/3

[Jan 11, 2011] Advanced redirection features

5.2.2.3. Writing to output and files simultaneously

You can use the tee command to copy input to standard output and one or more output files in one move. Using the -a option to tee results in appending input to the file(s). This command is useful if you want to both see and save output. The > and >> operators do not allow to perform both actions simultaneously.

This tool is usually called on through a pipe (|), as demonstrated in the example below:

> date | tee file1 file2
Thu Jun 10 11:10:34 CEST 2004

 > cat file1
Thu Jun 10 11:10:34 CEST 2004

 > cat file2
Thu Jun 10 11:10:34 CEST 2004

 > uptime | tee -a file2
 11:10:51 up 21 days, 21:21, 57 users,  load average: 0.04, 0.16, 0.26

 > cat file2
Thu Jun 10 11:10:34 CEST 2004
 11:10:51 up 21 days, 21:21, 57 users,  load average: 0.04, 0.16, 0.26

Linux I-O Redirection

Cool commands

Capturing stderr with tee. Swapping stderr and stdout

(((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 \
| tee stderr.txt) 3>&1 1>&2 2>&3) 1>out.txt 2>err.txt
The following section will walk through the theory behind this command. Once you have a general understanding of this theory, you should be able to easily regenerate this entire command without notes.
  1. Contents of the ./cmd script
    #!/bin/sh
    #You can use this sample script for testing.  The echo
    #    statements explain how this script works.
    echo "This is Standard Out" >&1
    echo "This is Standard Error" >&2
  2. Results from running the ./cmd script
    ./cmd
    This is Standard Out
    This is Standard Error
    #
    Although you see both lines printed on the screen, behind the scenes one actually went to stdout and the other went to stderr. If you were to do a pipe, only stdout goes through the pipe. Normally this is the desired effect.

  3. Capturing stdout

    The following will capture a copy of stdout and save it to a file called "stdout.txt"

    ./cmd | tee stdout.txt
    

    stdout goes through the pipe and tee is able to save a copy of it to the file "stdout.txt"; however, we just lost control of stderr. stderr will not go through the pipe, instead it goes directly to our display.

  4. Gaining control of stderr and stdout.

    Lets gain control again of stderr and stdout. We do this by surrounding our command with a set of parenthesis.

    (./cmd | tee stdout.txt)
    
  5. Swapping stdout and stderr.

    Now that we have captured stdout, we wish to capture stderr using tee as well. The pipe will only accept stdout, so we must swap stderr and stdout to do this.

    Note: The switch is using the standard variable switch method -- 3 variables (buckets) are required to swap 2 variables with each other. (you have 2 variables and you need to switch the contents - you must bring in a 3rd temporary variable to hold the contents of one value so you can properly swap them).

    (./cmd | tee stdout.txt) 3>&1 1>&2 2>&3
    
  6. Capturing stderr

    Now that we have swapped our stdout and stderr, lets hook up tee once again. tee will now capture stderr (tee believes that it is really stdout because stdout is the only thing that can come through the pipe).

    (./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 \
    | tee stderr.txt
    

  7. Gaining control of stderr and stdout, for the 2nd time.

    Tee grabs stderr, but once again the channel that doesn't go through the pipe gets sent to the display and we loose it. Lets capture both our stderr and stdout, once again, by using parenthesis.

    ((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 \
    | tee stderr.txt)
    
  8. Swapping stdout and stderr back to their normal state.

    Now we have, once again, captured both stderr and stdout for our use. Currently they are reversed. Lets switch them back for proper use in our pipeline. Again, lets use the standard variable switch to swap them around.

    ((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 \
    | tee stderr.txt) 3>&1 1>&2 2>&3
    

  9. Gaining control of stderr and stdout, for the 3rd time.

    At this point we have swapped stdout and stderr back to their normal positions; however, if we will be manipulating stdout and stderr any further, we should complete this command with either a pipe or another set of parenthesis.

    Since we want to be as complete as possible in this example we will use parenthesis. Using parenthesis will gain control over both stdout and stderr. Using a pipe will only gain control over stdout.

    Note: If we use a pipe or parenthesis the next process that hooks up to this command will see stderr and stdout in their proper place. If we don't add the last set of parenthesis, or go through a pipe, the order will remain messed up.

    (((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 \
    | tee stderr.txt) 3>&1 1>&2 2>&3)
    

  10. Redirecting stdout and stderr to separate files

    Now lets do something productive with stdout and stderr so that we can really prove that everything went back to their proper place. Lets tell our command to redirect stdout to "out" and stderr to "err".

    (((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 \
    | tee stderr.txt) 3>&1 1>&2 2>&3) 1>out.txt 2>err.txt
    

    Note: This last step is optional, normally you would insert your other required commands here, commands that would more than likely operate on stdout.

    Please note that the results for "out" and "err" are the same as when you run the following command. This proves that we restored stdout and stderr back to their normal usable posisitions. The above command; however, gives us the capability to copy out stdout and stderr using tee and still be able to use stdout and stderr like we always have.

    ./cmd 1>out.txt 2>err.txt
    

Capturing stderr in one file and stderr and stdout combined in another file

I had a request for stderr in 1 file and stderr and stdout combined in another file so here it is:

Here is our testing command we will use to generate both stderr 
and stdout on proper channels:
root@server:~> (echo out >&1; echo err >&2)
out
err
And here is the command to do the work:
root@server:~> (((echo out >&1; echo err >&2) 3>&2 2>&1 1>&3 | \
tee stderr.txt ) 3>&2 2>&1 1>&3 ) > combined.txt 2>&1
root@server:~> cat stderr.txt
err
root@server:~> cat combined.txt
out
err
root@server:~>

Please keep in mind when reading a book or web page with command line documentation
that the trailing slash signifies continuation of the current line. The reason for
this is due to the line width available on the screen and printed page. Note that
the trailing slash must be the last character on the line followed by enter. Spaces,
tabs, etc., may not apear after the trailing backslash because that does not signify
line continuation but rather some form of escape character. There are two ways that
you may enter this information at the command line:

1. Exactly as show, with the backslashes, followed by enter marks or

(((echo out >&1; echo err >&2) 3>&2 2>&1 1>&3 \
| tee stderr.txt ) 3>&2 2>&1 1>&3 ) > combined.txt 2>&1


2. Remove the trailing backslashes and do not press enter after each line, just word wrap
the lines together at the command prompt.

(((echo out >&1; echo err >&2) 3>&2 2>&1 1>&3 | tee stderr.txt ) 3>&2 2>&1 1>&3 ) > combined.txt 2>&1

Other Good Reading:

jobcontrol.html
man bash


Contents of ./myprog.sh
#!/bin/bash
echo "Standard Out" >&1
echo "Standard Error" >&2

Break out Standard Out into stdout.log, Standard Error into stderror.log, then display both on the screen:

((( ./myprog.sh | tee stdout.log ) 3>&2 2>&1 1>&3 | tee stderr.log ) 3>&2 2>&1 1>&3 )

Note, the lines may not come in the same order as without the redirection.
Note, the outside set of parenthesis (and the last set of movement just inside that last set of parenthesis) places stdout back on "1" and stderr back on "2" just in case you want to manipulate them further.

Break out Standard Out into stdout.log, Standard Error into stderror.log, combine the output (stdout and stderr), then display both on the screen:

((( ./myprog.sh | tee stdout.log ) 3>&2 2>&1 1>&3 | tee stderr.log ) 3>&2 2>&1 1>&3 ) 2>&1 | tee combined.log

TTTT tee

Sometimes you want to be able to monitor the progress of a long running process, but you also want to save a transcript of its output so you don't have to watch it every second.

tee was designed with this very purpose in mind.

% ls -l | tee foobar
total 26
-rw-r--r--  1 jeffy          28 May  9 16:12 Makefile
-rwxr-xr-x  1 jeffy       24576 May 28 11:31 foo
-rw-r--r--  1 jeffy          57 May  9 16:13 foo.c
% ls
Makefile        foo             foo.c           foobar
% cat foobar
total 26
-rw-r--r--  1 jeffy          28 May  9 16:12 Makefile
-rwxr-xr-x  1 jeffy       24576 May 28 11:31 foo
-rw-r--r--  1 jeffy          57 May  9 16:13 foo.c

Keep in mind that tee only duplicates stdout, so if you want to save error output (you probably do), you'll need to combine stderr onto stdout with "|&" if you're in csh-land, or "2>&1" if you're playing with sh.

Also note that tee accepts a "-a" flag which tells it to append its output to the file instead of truncating the file first.

Why's it called tee, you ask? Named after the pipe fitting that looks like a letter "T" and sends its input to two different places.

tee is also distinguished by having one of the shorter man pages in UNIXdom.


% cd /vobs/App/Mr
% clearmake |& tee Transcript

Recommended Links

Google matched content

Softpanorama Recommended

Top articles

Sites

Internal:

External:



Etc

Society

Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers :   Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy

Quotes

War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard Shaw : Mark Twain Quotes

Bulletin:

Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 :  Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method  : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law

History:

Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Hater’s Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor

The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D


Copyright © 1996-2021 by Softpanorama Society. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.

This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to to buy a cup of coffee for authors of this site

Disclaimer:

The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.

Last modified: April 29, 2021