如何在管道中使用“tee”时将stderr写入文件?

我知道如何使用teeaaa.sh的输出(STDOUT)写入bbb.out,同时仍在终端中显示:

/aaa.sh |三通bbb.out

我现在如何将STDERR写入名为ccc.out的文件,同时仍显示该文件

我假设你还想在终端上看到STDERR和STDOUT。你可以选择Josh Kelley的答案,但我发现在后台保留一个尾巴,这会输出你的日志文件,非常粗糙和笨拙。请注意,您需要如何保存exra FD并在事后通过杀死它来进行清理,从技术上讲,应该在陷阱“…”退出中进行清理

有一种更好的方法可以做到这一点,您已经发现了:tee

只是,不要只是在stdout中使用它,而是为stdout和stderr分别准备一个T恤。你将如何做到这一点?进程替换和文件重定向:

命令&gt&燃气轮机;(T形三通-标准对数)2&gt&燃气轮机;(T形三通-标准日志>&2)

让我们分开来解释一下:

&gt&燃气轮机;(..)

>(…)(进程替换)创建一个FIFO并让tee监听它。然后,它使用&gt(文件重定向)将命令的STDOUT重定向到第一个tee正在侦听的FIFO

第二件事也是这样:

2&gt&燃气轮机;(T形三通-标准日志>&2)

我们再次使用进程替换来创建一个tee进程,该进程读取STDIN并将其转储到stderr.logtee将其输入输出回STDOUT,但由于其输入是我们的STDERR,因此我们希望将tee的STDOUT再次重定向到我们的STDERR。然后我们使用文件重定向将命令的STDERR重定向到FIFO的输入(tee的STDIN)

看http://mywiki.wooledge.org/BashGuide/InputAndOutput

进程替换是选择bash作为shell而不是sh(POSIX或Bourne)的额外好处之一


sh中,您必须手动执行以下操作:

out=“${TMPDIR:-/tmp}/out.$$”err=“${TMPDIR:-/tmp}/err.$$”
mkfifo“$out”“$err”
陷阱“rm”$out“$err”退出
T形三通-a stdout.log<“$out”&
T形三通-a stderr.log<“$err”&gt&二,;
指挥部>“$out”2>“$err”

发表评论