如何将标准错误和标准输出重定向到多个位置?

3
我需要在Bash脚本(在FreeBSD6上)中执行一个命令,并且我需要将该命令的stderr和stdout发送到控制台、日志文件和Bash变量中。因此,不使用任何重定向,我想要的是:
result=`./command | tee output.log`

如果我按照原样运行,只有stderr会出现在控制台上,而stdout则会同时出现在output.log文件和$result变量中。我理解其中的原因,但是多次尝试不同的重定向方式都未能将这两个流发送到所有三个位置。
如何将stderr和stdout发送到所有三个位置?
1个回答

5
result=`./command 2>&1 | tee output.log | tee /dev/tty`

如n.m.在评论中指出,tee接受多个参数:
result=`./command 2>&1 | tee output.log /dev/tty`

借鉴来自评论区的Chris的想法,你也可以使用以下方法将输出发送到stderr:
result=`./command 2>&1 | tee /tmp/foo.log >(cat 1>&2)`

为了做到您所想要的,我发现最好的方法是这个:
exec 3>&1 ; result=`./command 2>&1 | tee /tmp/foo.log >(cat 1>&3)` ; exec 1>&3

整个问题在于反引号在内部任何东西执行之前重定向了标准输出。因此,这一行代码将旧的stdout保存并恢复为描述符3,这可能是一个好主意,也可能不是...

3
tee 命令可以接受任意数量的参数,例如 ... | tee output.log /dev/tty。它会将输入内容同时输出到指定的文件 output.log 和终端窗口 /dev/tty 中。 - n. m.
这种方法的一个问题是 - 如果我想将输出重定向到另一个文件,我的父bash脚本的输出将无法被重定向到那里。 - Anna M
在支持的系统上,您可以使用/dev/fd/2代替/dev/tty,但这将会将所有输出发送到stderr(以及日志文件和$result),这可能也不是您想要的。 - Chris Dodd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接