一个Bash重定向的问题

网上有人问到一个有意思的问题:如何把一个命令的输出同时重定向到3个文件?分别是:标准输出一个,标准错误输出一个,这两个都有又是一个。

我一开始以为这个不难,但我仔细想想发现不是,根本就没那么简单!首先一个问题,你重定向某个文件句柄到文件(或者另一个句柄)后意味着后面你就得不到了;其次,复制一个流我们的工具只有tee。所以,我们可以看出,这里tee至少得被调用两次才可以,因为两个流被都被复制一次。我的想法是:先tee标准输出,然后交换1和2,再tee标准错误,然后再重定向1和2到文件。

我还没来得及把想法付诸于实践,别人就有解答了,而且他的比我的还简单!看了他的我反省了一下自己的解法,第2步其实没必要交换,因为1已经被重定向过了,只需要一个临时的把它保存一下即可,下面是他的解答:

{ { your_cmd | tee stdout; } 2>&1 1>&3 | tee stderr 1>&3; } 3>stdout+err

作者说应该还有更简单的,但我是想不起来了。有知道的还望不吝赐教!(自己重写个tee不算,请用已有的命令。)

如果你觉得上面的重定向难理解,那下面这个呢?:-)

{
  {
    cmd1 3>&- |
      cmd2 2>&3 3>&-
  } 2>&1 >&4 4>&- |
    cmd3 3>&- 4>&-

} 3>&2 4>&1