【发布时间】:2012-01-04 00:13:30
【问题描述】:
我目前正在使用以下内容来捕获进入终端的所有内容并将其放入日志文件中
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
)
除了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"
终端的输出符合预期,并且日志文件中没有所需的颜色转义码/杂乱。然而,在检查
test.log时,我没有看到[READ] ...(参见test.sh的第 21 行)。[我的实际 bash 脚本的] 日志文件在其末尾包含
Log File: ...行,即使在关闭 4 和 5 fds 之后也是如此。我可以通过在第二个exec之前放置一个sleep 1来解决这个问题——我认为这应该归咎于竞争条件或fd 恶作剧。对你们来说不幸的是,我无法使用test.sh重现此问题,但我会对任何人的猜测感兴趣。
【问题讨论】:
-
请注意,\e[...m 代码特定于 VT100/VT200/等。并且可能不是程序在不同类型的 $TERM 上实际输出的那些。