bash tee去除颜色

And*_*ohn 9 bash logging exec tee

我目前正在使用以下内容来捕获发送到终端的所有内容并将其放入日志文件中

exec 4<&1 5<&2 1>&2>&>(tee -a $LOG_FILE)
Run Code Online (Sandbox Code Playgroud)

但是,我不希望颜色转义码/杂乱进入日志文件.所以我有类似的东西,sorta工作

exec 4<&1 5<&2 1>&2>&>(
    while read -u 0; do
        #to terminal
        echo "$REPLY"
        #to log file (color removed)
        echo "$REPLY" | sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' >> $LOG_FILE
    done
    unset REPLY #tidy
)
Run Code Online (Sandbox Code Playgroud)

除了read等待回车,这对于脚本的某些部分是不理想的(例如echo -n "..."printf没有\n).


Jonathan Leffler回答的后续行动:

给出示例脚本test.sh:

#!/bin/bash

LOG_FILE="./test.log"
echo -n >$LOG_FILE

exec 4<&1 5<&2 1>&2>&>(tee -a >(sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' > $LOG_FILE))


##### ##### #####
# Main

echo "starting execution"
printf "\n\n"

echo "color test:"
echo -e "\033[0;31mhello \033[0;32mworld\033[0m!"
printf "\n\n"

echo -e "\033[0;36mEnvironment:\033[0m\n  foo: cat\n  bar: dog\n  your wife: hot\n  fix: A/C"
echo -n "Before we get started. Is the above information correct?  "
read YES
echo -e "\n[READ] $YES" >> $LOG_FILE
YES=$(echo "$YES" | sed 's/^\s*//;s/\s*$//')
test ! "$(echo "$YES" | grep -iE '^y(es)?$')" && echo -e "\nExiting... :(" && exit
printf "\n\n"

#...some hundreds of lines of code later...

echo "Done!"


##### ##### #####
# End

exec 1<&4 4>&- 2<&5 5>&-

echo "Log File: $LOG_FILE"
Run Code Online (Sandbox Code Playgroud)
  1. 到终端的输出是预期的,并且根据需要在日志文件中没有颜色转义码/杂乱.但经过检查test.log,我没有看到[READ] ...(见第21行test.sh).

  2. [我的实际bash脚本]的日志文件包含Log File: ...在它结束时的行,即使在关闭4和5 fds之后.我能够通过sleep 1在第二个之前放一个来解决这个问题exec- 我认为有一个竞争条件或fd shenanigans应该归咎于它.对你们来说不幸的是,我无法重现这个问题,test.sh但我对任何人可能有的猜测感兴趣.

Jon*_*ler 5

考虑使用是否可以在并行进程上分发 stdin 中pee讨论的程序。它允许您通过 sed 脚本发送日志数据,同时继续将颜色发送到实际输出。

这样做的一个主要优点是它将删除“sed每行日志输出执行一次”;这对性能来说真的很糟糕(就执行的进程数而言,如果没有别的的话)。

  • 出色的!谢谢你!`exec 4&lt;&amp;1 5&lt;&amp;2 1&gt;&amp;2&gt;&amp;&gt;(tee -a &gt;(sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1 ,2})?)?[m|K]//g' &gt; $LOG_FILE))` (2认同)