简体   繁体   English

将stderr和stdout写入一个文件,但也将stderr写入另一个文件

[英]Write stderr and stdout to one file, but also write stderr to a separate file

I have a shell script whose stdout and stderr I want to write to a logfile. 我有一个Shell脚本,我要将其stdout和stderr写入日志文件。 I know that this can be achieved via 我知道这可以通过

sh script.sh >> both.log 2>&1

However, I also want to simultaneously write the stderr to a separate file, "error.log". 但是,我也想同时将stderr写入一个单独的文件“ error.log”。 Is this achievable? 这可以实现吗?

You can use tee to duplicate output to two locations. 您可以使用tee将输出复制到两个位置。 Combine that with some tricky redirections, and... 结合一些棘手的重定向,然后...

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

This redirects stderr to stdout, and then stdout to both.log . 这会将stderr重定向到stdout,然后将stdout重定向到both.log stderr remains, and is piped to tee , which copies it to both log files. stderr保留下来,并通过管道传递到tee ,然后将它复制到两个日志文件中。

For this you need to first switch stdout and stderr, which requires an additional file descriptor: 为此,您需要首先切换stdout和stderr,这需要一个附加的文件描述符:

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

The last operator closes the auxiliary file descriptor. 最后一个运算符关闭辅助文件描述符。

After that you can use tee to duplicate the error stream (which is now on stdin) and append it to your error log: 之后,您可以使用tee复制错误流(现在在stdin上)并将其附加到错误日志中:

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

And after that you can then direct both stdin and stderr to your combined log: 然后,您可以将stdin和stderr都指向合并的日志:

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

The parentheses around the command are important to capture the error stream of the whole command. 命令周围的括号对于捕获整个命令的错误流很重要。 Without them only the (empty) error stream of the tee command would be captured and the rest would still go to the terminal. 没有它们,只会捕获tee命令的(空)错误流,其余的仍将流向终端。

Note: this does not check wheater the file descriptor 3 was in use (open) before. 注意:这不会检查文件描述符3之前是否已使用(打开)。 In bash you can use this to choose a previously unused file descriptor and close it on the last redirection: 在bash中,您可以使用它来选择以前未使用的文件描述符,并在最后一次重定向时将其关闭:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM