将stdout和stderr重定向到不同的程序而不更改退出代码

时间:2014-12-06 05:38:07

标签: linux bash

This post基本上问同样的问题,但我想要一个额外的要求,即:退出代码应保持不变。

接受的答案使用管道,因此退出代码不再是command1的退出代码。

命令集pipefail并不符合我的需要,因为我不想在执行command1时影响行为,这可能是复合Bash命令本身。

我尝试了以下方法,但输出不符合预期:

[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

有人可以说出原因吗?

3 个答案:

答案 0 :(得分:0)

你在输出中得到xx yy hehe的原因是因为来自第二个while循环的yy hehe行也被写在stdout上并被送到第一个while read循环因此成为{{1 }}

您可以使用此脚本:

xx yy hehe

编辑:以这种方式显示退出代码如何保持不变

{ 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

EDIT2 显示如何使用备用文件描述符进行重定向:

{ 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

答案 1 :(得分:0)

This was answered早在2012年。原因是因为替换是 并非所有人都在同一时间完成。解决方法是将stderr与stderr保持一致。

foo > >(baz) 2> >(qux 1>&2)

答案 2 :(得分:0)

我自己找到了答案:

command1 3>&1 4>&2 1> >(command2 1>&3 2>&4) 2> >(command3 1>&3 2>&4)

这样,无论command2command3输出到stdout还是stderr,都没有问题。