只通过filterpipe道stderr

有没有什么办法,在bash中,将stderr通过filter统一到标准输出之前? 那就是我想要的

stdout ----------------\ |-----> terminal/file/whatever stderr -- [ filter ] --/ 

而不是

 stdout ----\ |----[ filter ]---> terminal/file/whatever stderr ----/ 

这是一个例子,模拟如何在bash中交换文件描述符 。 a.out的输出如下,没有“STDXXX:”前缀。

 STDERR: stderr output STDOUT: more regular ./a.out 3>&1 1>&2 2>&3 3>&- | sed 's/e/E/g' more regular stdErr output 

从上面的链接引用:

  1. 首先保存stdout为&3(&1被骗入3)
  2. 接下来发送stdout到stderr(&2被骗入1)
  3. 发送stderr到&3(stdout)(&3被骗入2)
  4. closures&3(& – 被骗入3)

过程replace的一个天真的使用似乎允许从stdout单独过滤stderr

 :; ( echo out ; echo err >&2 ) 2> >( sed s/^/e:/ >&2 ) out e:err 

请注意stderr stderrstdout stdout ,我们可以看到通过包装整个事情在另一个子shell和redirect到文件oe

 ( ( echo out ; echo err >&2 ) 2> >( sed s/^/e:/ >&2 ) ) 1>o 2>e 

我发现使用bash过程replace更容易记住和使用,因为它几乎是逐字地反映了初衷。 例如:

 $ cat ./p echo stdout echo stderr >&2 $ ./p 2> >(sed -e 's/s/S/') | sed 's/t/T/' sTdout STderr 

使用第一个sed命令作为stderr上的filter,第二个sed命令修改连接的输出。

请注意,2>之后的空白区域对于正确parsing命令是强制性的。

“高级Bash脚本指南”的这个页面的最后一部分是“仅将stderrredirect到pipe道”。

#只有stderrredirect到pipe道。

 exec 3>&1 # Save current "value" of stdout. ls -l 2>&1 >&3 3>&- | grep bad 3>&- # Close fd 3 for 'grep' (but not 'ls'). # ^^^^ ^^^^ exec 3>&- # Now close it for the remainder of the script. 

谢谢,SC

这可能是你想要的。 如果没有,ABSG的其他部分应该能够帮助你,这是非常好的。

看看命名pipe道:

 $ mkfifo err $ cmd1 2>err |cat - err |cmd2