我目前正在使用以下代码来捕获所有传输到终端的内容并将其记录到日志文件中
exec 4<&1 5<&2 1>&2>&>(tee -a $LOG_FILE)
然而,我不希望颜色转义代码或杂乱无章的内容出现在日志文件中。 所以我有类似这样的东西,有点起作用。
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
)
except read
等待回车符,这对于脚本的某些部分来说并不理想(例如没有 \n
的 echo -n "..."
或 printf
)。
回应 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"
终端输出结果符合预期,在日志文件中也没有颜色转义码或混乱的内容,正如预期一样。然而,在检查
test.log
时,我没有看到[READ] ...
的内容(请见test.sh
的第21行)。我的实际bash脚本的日志文件在关闭4和5个fds后仍包含
Log File: ...
这一行。我通过在第二个exec
之前放置sleep 1
来解决了这个问题 - 我认为这可能是由于竞争条件或fd操作导致的。不幸的是,我无法通过test.sh
重现这个问题,但我会对任何人的猜测感兴趣。