球座

球座

所以,假设我有一个这样的脚本。

log_files=(output_{console,stdout,stderr}.log)
do_stuff 2>"${log_files[2]}" 1>"${log_files[1]}"

虽然该函数应该将 stdout 重定向到"${log_files[1]}"stderr "${log_files[2]}",但我也希望"${log_files[0]}"同时将 stdout 和 stderr 重定向到。如何才能做到这一点?

答案1

这在 zsh 中会容易得多,multios如果同一个 fd 上有多个重定向,shell 会执行一些内部魔法将输出发送到所有目的地,例如:

% do_stuff > stdout.log 2> stderr.log &> both.log

(请注意,由于处理重复输出的中间进程,输出到 stdout 和 stderr 之间的顺序可能会混淆。)

答案2

球座

回想一下echo "foo" | tee --append log.txt球座 将“foo”发送到文件和文件描述符 1。

这会将“foo”放入一对文件中:

echo "foo" | tee --append one.txt  >> two.txt

因此,您可以重定向到一对子 shell,每个子 shell 将传入文本记录到一对文件中。

命名管道

如果您需要更大的灵活性,您也可以创建命名管道,然后对结果应用任意逻辑。

$ mkfifo /tmp/stdout
$ mkfifo /tmp/stderr

将文件描述符 1 和 2 发送给它们,就像您已经在做的那样。在另一个终端选项卡或后台守护程序中,运行tail -f或其道德等效项以从每个终端检索文本行先进先出实时。使用正则表达式进行过滤,用时间戳进行修饰,做任何您喜欢的事情,然后将结果写入您想要的任意数量的接收器。

答案3

或者,要在没有命名管道的情况下执行此操作,您可以使用此问题的答案:https://stackoverflow.com/questions/16497317/piping-both-stdout-and-stderr-in-bash

将 stdout 和 stderr 分别通过管道传输到它们自己的 tee 副本,两者都附加到同一文件,并写入所需的各个文件。

然而,并非所有 tee 的实现都会安全地执行此操作,因此在某些情况下,您可能最终会在“both”文件中奇怪地散布 stdout 和 stderr 块。

据我所知,tee 没有办法强制进行安全的基于行的缓冲。

相关内容