问题
This post basically asks the same question but I want an additional requirement, which is: the exit code should be unchanged.
The accepted answer uses pipe, so the exit code is no longer the exit code of command1.
Command set pipefail doesn't fit my need as I don't want to affect the behavior when executing command1, which might be a compound Bash command itself.
I tried the following approach, but the output is not as expected:
[hidden]$ (echo haha; echo hehe 1>&2) > >(while read -r x; do echo "xx $x"; done)
2> >(while read -r y; do echo "yy $y"; done)
xx haha
xx yy hehe
Can anyone tell why?
回答1:
This was answered back in 2012. The reason is because the substitutions are not all done at the same time. A workaround is to keep stderr with stderr.
foo > >(baz) 2> >(qux 1>&2)
回答2:
I found the answer myself:
command1 3>&1 4>&2 1> >(command2 1>&3 2>&4) 2> >(command3 1>&3 2>&4)
In this way, no matter command2 and command3 output to stdout or stderr, there will be no problem.
回答3:
The reason why you get xx yy hehe in your output because yy hehe line from 2nd while loop is also being written on stdout and being fed to the first while read loop thus becoming xx yy hehe
You can use this script:
{ echo haha; echo hehe >&2; } 2> >(while read -r y; do echo "yy $y"; done) > >(while read -r x; do echo "xx $x"; done)
yy hehe
xx haha
EDIT: To show how exit code remains unchanged this way:
{ echo haha; ls hehe >&2; } 2> >(while read -r y; do echo "yy $y"; done) > >(while read -r x; do echo "xx $x"; done); echo "exit status: $?"
xx haha
yy ls: cannot access hehe: No such file or directory
exit status: 2
EDIT2 To show how to use alternate file descriptors for redirecting:
{ date >&5; ls hehe >&6 2>&6; } \
5> >(while read -r x; do echo "xx: $x"; done) \
6> >(while read -r y; do echo "yy: $y"; done); \
echo "exit status: $?"; 5>&- && 6>&-
xx: Sat Dec 6 03:25:20 EST 2014
yy: ls: cannot access hehe: No such file or directory
exit status: 2
来源:https://stackoverflow.com/questions/27328692/redirect-stdout-and-stderr-to-different-program-without-changing-exit-code