如何让 bash 将 stderr 重定向到 >( 命令替换)?

and*_*sel 4 bash redirect

我可以很好地将标准输出重定向到命令重定向:

$ ( echo stdout ; >&2 echo stderr  ) > >( rev )
stderr
tuodts
Run Code Online (Sandbox Code Playgroud)

但是当我尝试将 stderr 重定向到另一个时,它似乎通过了 stdout 通道:

$ ( echo stdout ; >&2 echo stderr  ) > >( rev ) 2> >( cat )
tuodts
rredts
Run Code Online (Sandbox Code Playgroud)

我不能使用管道,因为我想严格分开处理:

$ ( echo stdout ; >&2 echo stderr ) 2> >(rev)
stdout
rredts
Run Code Online (Sandbox Code Playgroud)

这会做一些奇怪的事情:

$ ( echo stdout ; >&2 echo stderr ) 2> >(rev) | cat -n
 1  stdout
 2  rredts
Run Code Online (Sandbox Code Playgroud)

我误解了这应该如何工作吗?

(我的实际目标是让 stdout 和 stderr 经历两个不同的 tee 进程,同时为现有的消费进程保留明显的 stderr 和 stdout。)

GNU bash,版本 3.2.57(1)-release-(x86_64-apple-darwin15)

Joh*_*024 5

进行重定向时,顺序很重要。

您需要颠倒顺序:

$ ( echo stdout ; >&2 echo stderr  ) 2> >( cat ) > >( rev )
stderr
tuodts
Run Code Online (Sandbox Code Playgroud)

讨论

考虑原始代码:

$ ( echo stdout ; >&2 echo stderr  ) > >( rev ) 2> >( cat )
tuodts
rredts
Run Code Online (Sandbox Code Playgroud)

stderr 确实被传递到cat cat将其输出发送到 stdout 并且 stdout已经被重定向到rev. 因此, stdout 和 stderr 最终都会转到rev.

如果我们颠倒顺序(如上),cat则将其输出发送到终端,因为 stdout尚未重定向。

选择

这是防止 stderr 被捕获的另一种方法rev

$ ( echo stdout ; >&2 echo stderr  ) > >( rev ) 2> >( cat >&2)
tuodts
stderr
Run Code Online (Sandbox Code Playgroud)