The regular output is sent to Standard Out (STDOUT) and the error messages are sent to Standard Error (STDERR). When you redirect console output using the > symbol, you are only redirecting STDOUT. In order to redirect STDERR, you have to specify 2> for the redirection symbol.
The append >> operator adds the output to the existing content instead of overwriting it. This allows you to redirect the output from multiple commands to a single file. For example, I could redirect the output of date by using the > operator and then redirect hostname and uname -r to the specifications.
There is also process substitution. Which makes a process substitute for a file.
You can send stderr
to a file as follows:
process1 2> file
But you can substitute a process for the file as follows:
process1 2> >(process2)
Here is a concrete example that sends stderr
to both the screen and appends to a logfile
sh myscript 2> >(tee -a errlog)
You can use the following trick to swap stdout
and stderr
. Then you just use the regular pipe functionality.
( proc1 3>&1 1>&2- 2>&3- ) | proc2
Provided stdout
and stderr
both pointed to the same place at the start, this will give you what you need.
What the x>&y
bit does is to change file handle x
so it now sends its data to wherever file handle y
currently points. For our specific case:
3>&1
creates a new handle 3
which will output to the current handle 1
(original stdout), just to save it somewhere for the final bullet point below.1>&2
modifies handle 1
(stdout) to output to the current handle 2
(original stderr).2>&3-
modifies handle 2
(stderr) to output to the current handle 3
(original stdout) then closes handle 3
(via the -
at the end).It's effectively the swap command you see in sorting algorithms:
temp = value1;
value1 = value2;
value2 = temp;
Bash 4 has this feature:
If `|&' is used, the standard error of command1 is connected to command2's standard input through the pipe; it is shorthand for 2>&1 |. This implicit redirection of the standard error is performed after any redirections specified by the command.
zsh also has this feature.
--
With other/older shells, just enter this explicitly as
FirstCommand 2>&1 | OtherCommand
Swapping is great as it solves the problem. Just in case you do not even need the original stdout, you can do it this way:
proc1 2>&1 1>/dev/null | proc2
The order is vital; you would not want:
proc1 >/dev/null 2>&1 | proc1
As this will redirect everything to /dev/null
!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With