|
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 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
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.Using the tee command to append stdout to tee.txt. stdout is still displayed on the screen.cmd | tee tee.txt
cmd | tee -a tee.txt
Extracting users from etc passwd and printing them and displaying on the sceeen simultaniouly:
The following command copies stdout and stderr to the files "stdout.txt" and "stderr.txt", respectively.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.
(((./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.txtThe walk through <
- 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- 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.
- Capturing stdout
The following will capture a copy of stdout and save it to a file called "stdout.txt"
./cmd | tee stdout.txtstdout 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.- 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)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- 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- 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)- 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- 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)- 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.txtNote: 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.txtCapturing 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
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 processesecho "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 concurrentlydd if=/dev/sda | tee >(dd of=/dev/sdb) | dd of=/dev/sdcIf 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=64k
To image more drives , insert them as additional arguments to tee:4) Save a file you edited in vim without the needed permissions (no echo)
dd if=/dev/sda | tee >(dd of=/dev/sdb) >(dd of=/dev/sdc) >(dd of=/dev/sdd) | dd of=/dev/sde
:w !sudo tee > /dev/null %
5) run command on a group of nodes in parallel
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.echo “uptime” | tee >(ssh host1) >(ssh host2) >(ssh host3)
6) tee to a file descriptortee >(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 sudoecho “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/file
does NOT add to the file as root.Alternatively,
sudo echo "foo bar" > /path/to/some/file
should be replaced by
echo "foo bar" | sudo tee /path/to/some/file
And you can add a >/dev/null in the end if you’re not interested in the tee stdout :8) Save a file you edited in vim without the needed permissions – (Open)solaris version with RBAC
echo "foo bar" | sudo tee -a /path/to/some/file >/dev/null
:w !pfexec tee %
9) bash or tcsh redirect both to stdout and to a fileecho “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 diskcat /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 fileecho “text” | sudo tee -a /path/file.conf > /dev/null
You can add repositories, options etc to any .conf in your system!
|
Switchboard | ||||
Latest | |||||
Past week | |||||
Past month |
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 | 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 | 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.txtOutput:
... ... ...
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 fileAfter 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 >(dd of=/dev/sdb) | dd of=/dev/sdcIf 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/sde5) 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 >(ssh host1) >(ssh host2) >(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/3script /dev/null | tee /dev/pts/3
5.2.2.3. Writing to output and files simultaneouslyYou 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
Cool commands
- The following command saves stdout and stderr to the files "out.txt" and "err.txt", respectively.
./cmd 1>out.txt 2>err.txt- The following command appends stdout and stderr to the files "out.txt" and "err.txt", respectively.
./cmd 1>>out.txt 2>>err.txt- The following command functions similar to the above two commands, but also 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.txtNote: Lines that end in a backslash are continued on the next line. Any such lines should be keyed in as one complete line. The lines are too long to fit on the web page without formatting them this way.
- Cool Tar Command
(cd /var/ftp/pub/rh71prof/disk1.iso.dir \ && tar -cvf - .) | (cd /var/ftp/pub/rh71prof/i386 && tar -xvf -)Note: Lines that end in a backslash are continued on the next line. Any such lines should be keyed in as one complete line. The lines are too long to fit on the web page without formatting them this way.
- Cool Find Command - looks in each file for search string
find . -type f -exec grep -i searchstring --with-filename {} \;Note: Lines that end in a backslash are continued on the next line. Any such lines should be keyed in as one complete line. The lines are too long to fit on the web page without formatting them this way.
- Sample Test 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- For loop demonstrating stderr and stdout
echo Standard Out >stdout.txt echo Standard Error >stderr.txt for X in bzImage modules modules_install; do make $X; done 1>>stdout.txt 2>>stderr.txtRedirection in Linux
0 = stdin
1 = stdout
2 = stderr- 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- Using the script command to capture both stderr and stdout
[root@server stdout]# script Script started, file is typescript [root@server stdout]# ./cmd This is Standard Out This is Standard Error [root@server stdout]# exit exit Script done, file is typescript [root@server stdout]# cat typescript Script started on Thu Oct 11 11:47:36 2001 [root@server stdout]# ./cmd This is Standard Out This is Standard Error [root@server stdout]# exit exit Script done on Thu Oct 11 11:47:39 2001 [root@server stdout]#- Notes about pipe "|"
- Lets consider a channel one of stdout or stderr.
- The pipe can only carry one channel, namely stdout.
- When you have a command line which utilizes the pipe command, stderr gets sent to the display while stdout gets sent through the pipe on to the other awaiting commands.
- Swapping stdout and stderr will allow stdout to be sent to the display while stderr can be sent through the pipe.
- Pipe by itself will only take stdout. If you swap stdout and stderr before you get to the pipe then the pipe will take stdout (which is now stderr).
- stdout and stderr can be combined and sent through the pipe; however, you have now combined both stderr and stdout and there is no way to separate them.
- using a pipe in a subshell "()" causes stdout to go through the pipe and causes stderr to pass through the subshell back to the display. This provides a way to grab stdout and stderr. Basically you could get both stdout and stderr out of a subshell.
- Order of redirecting
- Method 1
cmd 2>&1 1> outfile.txt#The above command causes the original stderr to go to stdout,
# and causes the original stdout to go to outfile.txt.
#Notice at the time that fd (file descriptor) 2 is redefined, fd 1 still pointed to stdout; therefore, fd 2 will continue to point to stdout independently of what later happens to fd 1. Basically fd 2 copies the item (or address) that fd 1 is pointing to.
(Corrected an incorrect statement - Thanks to Morten for bringing it to my attention.)
- Method 2 #The following command causes both the original stdout and stderr to go to outfile.txt.
cmd 1>outfile.txt 2>&1
#Notice that 1=outfile.txt when 2 is redefined, so 2 goes to outfile.txt too (the two
# channels are combined).
Capturing stderr with tee. Swapping stderr and stdout
- 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.txtThe 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.
- The walk through
- 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- 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.
- 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.
- 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)- 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- 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
- 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)- 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
- 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)
- 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.txtCapturing 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" >&2Break 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
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
Google matched content |
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 quotes : Somerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose Bierce : Bernard 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 DOS : Programming Languages History : PL/1 : Simula 67 : C : History of GCC development : Scripting 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-Month : How 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