我可以很好地将标准输出重定向到命令重定向:
$ ( 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)
进行重定向时,顺序很重要。
您需要颠倒顺序:
$ ( 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)