问题
It's well known how to pipe the standard ouput of a process into another processes standard input:
proc1 | proc2
But what if I want to send the standard error of proc1 to proc2 and leave the standard output going to its current location? You would think bash would have a command along the lines of:
proc1 2| proc2
But, alas, no. Is there any way to do this?
回答1:
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)
回答2:
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 information to where file handle y currently points. For our specific case:
3>&1creates a new handle3which will output to the current handle1(original stdout), just to save it somewhere for the final bullet point below.1>&2modifies handle1(stdout) to output to the current handle2(original stderr).2>&3-modifies handle2(stderr) to output to the current handle3(original stdout) then closes handle3(via the-at the end).
It's effectively the swap command you see in sorting algorithms:
temp = value1;
value1 = value2;
value2 = temp;
回答3:
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
回答4:
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!
回答5:
None of these really worked very well. The best way I found do do what you wanted is:
(command < input > output) 2>&1 | less
This only works for cases where command does not need keyboard input. eg:
(gzip -d < file.gz > file) 2>&1 | less
would put gzip errors into less
来源:https://stackoverflow.com/questions/1507816/with-bash-how-can-i-pipe-standard-error-into-another-process