将stderr和stdout写入一个文件,但也将stderr写入单独的文件

时间:2017-02-15 14:00:25

标签: linux shell io scripting

我有一个shell脚本,我想将stdout和stderr写入日志文件。我知道这可以通过

来实现
sh script.sh >> both.log 2>&1

但是,我还想同时将stderr写入一个单独的文件," error.log"。这可以实现吗?

2 个答案:

答案 0 :(得分:4)

您可以使用tee将输出复制到两个位置。将它与一些棘手的重定向结合起来,然后......

script.sh 2>&1 >> both.log | tee -a both.log >> error.log

将stderr重定向到stdout,然后stdout重定向到both.log。 stderr仍然存在,并通过管道传输到tee,将其复制到两个日志文件中。

答案 1 :(得分:1)

为此,您需要先切换stdout和stderr,这需要一个额外的文件描述符:

sh script.sh 3>&2 2>&1 1>&3 3>&-

最后一个运算符关闭辅助文件描述符。

之后,您可以使用tee复制错误流(现在在stdin上)并将其附加到错误日志中:

sh script.sh 3>&2 2>&1 1>&3 3>&- | tee -a error.log

之后,您可以将stdin和stderr指向您的组合日志:

(sh script.sh 3>&2 2>&1 1>&3 3>&- | tee -a error.log) >> both.log 2>&1

命令周围的括号对于捕获整个命令的错误流非常重要。如果没有它们,只会捕获tee命令的(空)错误流,其余的仍然会转到终端。

注意:这不会检查文件描述符3之前是否正在使用(打开)。在bash中,您可以使用它来选择以前未使用的文件描述符,并在最后一次重定向时将其关闭:

sh script.sh {tmpfd}>&2 2>&1 1>&${tmpfd}-