当 stdout 重定向到文件时,将消耗的输出复制到 stdout

当 stdout 重定向到文件时,将消耗的输出复制到 stdout

给定一个正在处理其输出的命令,例如 grep,我还希望将实际输出包含在日志文件中以用于调试目的。

例如,如果我有以下内容

useful=$(curl -s http://example.com/some/data | grep 'useful line')
echo "useful=$useful"

我想看看

This page has a number of lines in it, but'
useful lines are the only ones I care about
except when something goes wrong and then
I'd really like to see what the heck was in
the output that grep consumed.
useful=useful lines are the only ones I care about

像这样完成 T 恤

useful=$(curl -s http://example.com/some/data | tee /proc/$$/fd/1 | grep 'useful line')
echo "useful=$useful"

如果 stdout 被重定向到一个文件,tee则会破坏日志文件的其余部分。tee -a以大致相同的方式失败。

答案1

tee流到stdout控制终端设备/dev/tty

(
exec 1> >(tee -a stdout.log)
: > stdout.log
#var="$(echo -e "one\ntwo" | tee /dev/tty | grep one)"
var="$(echo -e "one\ntwo" | tee -a /dev/tty stdout.log | grep one)"
echo "var=$var"
)

cat stdout.log
# one
# two
# var=one

答案2

我不清楚你是否想要 $var,或者 $var 只是达到目的的手段。要获取 $var,请添加var="$(cat log)"

sed -nre 'p;/one/w log' <(echo -e "one\ntwo")
  • --------(标准输出 )
    一二
  • --------(日志)

或者你的意思是这样的:

sed -nre 'p;/one/w log' -e 's/one/logged: &/p' <(echo -e "one\ntwo")
  • --------(stdout)记录


    一二
  • --------(日志)

注意:每次执行脚本时,sed 的w命令都会覆盖。log当然,您可以log在 sed 运行后附加到主日志。看:sed 命令摘要

答案3

为什么不直接使用一个函数:

#!/bin/bash
logAndEcho () {
    echo -e "$@" >> LOGFILE.txt
    echo -e "$@"
}
var=$(logAndEcho "one\ntwo\nThis is a test"|grep one)
echo "var=$var"

这会将整个结果发送到日志文件,然后将数据回显到标准输入,您可以在其中根据需要捕获它。

答案4

sed 就是为此而设计的——它是流编辑器。它可以取代您的进程中的 tee 和 grep,或者如果您愿意的话,可以与 tee 结合在您的 fork 中添加更多尖齿。不管怎样,你自己看看吧:

% sed '/useful/w ./useful.log' <<HDOC >>./notsomuch.log
> maybe useful
> definitely not
> ho-hum
> now this is useful
> HDOC
% cat ./useful.log
OUT> maybe useful
OUT> now this is useful
% cat ./notsomuch.log
OUT> maybe useful
OUT> definitely not
OUT> ho-hum
OUT> now this is useful

相关内容