bash tee 去除颜色
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8720508/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
bash tee remove color
提问by Andrew Sohn
I'm currently using the following to capture everything that goes to the terminal and throw it into a log file
我目前正在使用以下内容来捕获进入终端的所有内容并将其放入日志文件中
exec 4<&1 5<&2 1>&2>&>(tee -a $LOG_FILE)
however, I don't want color escape codes/clutter going into the log file. so i have something like this that sorta works
但是,我不希望颜色转义码/杂乱进入日志文件。所以我有类似这样的东西
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 readwaits for carriage return which isn't ideal for some portions of the script (e.g. echo -n "..."or printfwithout \n).
除了read等待回车,这对于脚本的某些部分(例如echo -n "..."或printf没有\n)来说并不理想。
Follow-up to Jonathan Leffler's answer:
Jonathan Leffler 回答的后续行动:
Given the example script test.sh:
鉴于示例脚本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 "3[0;31mhello 3[0;32mworld3[0m!"
printf "\n\n"
echo -e "3[0;36mEnvironment:3[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"
The output to the terminal is as expected and there is no color escape codes/clutter in the log file as desired. However upon examining
test.log, I do not see the[READ] ...(see line 21 oftest.sh).The log file [of my actual bash script] contains the line
Log File: ...at the end of it even after closing the 4 and 5 fds. I was able to resolve the issue by putting asleep 1before the secondexec- I assume there's a race condition or fd shenanigans to blame for it. Unfortunately for you guys, I am not able to reproduce this issue withtest.shbut I'd be interested in any speculation anyone may have.
终端的输出符合预期,并且日志文件中没有所需的颜色转义码/混乱。然而,在检查时
test.log,我没有看到[READ] ...(见第 21 行test.sh)。Log File: ...即使在关闭 4 和 5 fds 之后,[我的实际 bash 脚本的] 日志文件也包含它末尾的行。我能够通过sleep 1在第二个之前放置 a 来解决这个问题exec- 我认为这应该归咎于竞争条件或 fd 恶作剧。对你们来说不幸的是,我无法重现这个问题,test.sh但我对任何人可能有的猜测感兴趣。
采纳答案by Jonathan Leffler
Consider using the peeprogram discussed in Is it possible to distribute stdin over parallel processes. It would allow you to send the log data through your sed script, while continuing to send the colours to the actual output.
考虑使用是否可以在并行进程上分发 stdin 中pee讨论的程序。它允许您通过 sed 脚本发送日志数据,同时继续将颜色发送到实际输出。
One major advantage of this is that it would remove the 'execute sedonce per line of log output'; that is really diabolical for performance (in terms of number of processes executed, if nothing else).
这样做的一个主要优点是它将删除“sed每行日志输出执行一次”;这对性能来说真的很糟糕(就执行的进程数而言,如果没有别的的话)。
回答by Micha? ?rajer
I know it's not a perfect solution, but cat -vwill make non visible chars like \x1Bto be converted into visible form like ^[[1;34m. The output will be messy, but it will be ascii text at least.
我知道这不是一个完美的解决方案,但cat -v会使不可见的字符\x1B像^[[1;34m. 输出会很乱,但至少是 ascii 文本。
回答by David W.
I use to do stuff like this by setting TERM=dumbbefore running my command. That pretty much removed any control characters except for tab, CR, and LF. I have no idea if this works for your situation, but it's worth a try. The problem is that you won't see color encodings on your terminal either since it's a dumb terminal.
我过去常常通过TERM=dumb在运行我的命令之前进行设置来做这样的事情。这几乎删除了除制表符、CR 和 LF 之外的任何控制字符。我不知道这是否适合您的情况,但值得一试。问题是您也不会在终端上看到颜色编码,因为它是一个哑终端。
You can also try either visor cat(especially the -vparameter) and see if these do something for you. You'd simply put them in your pipeline like this:
您也可以尝试使用vis或cat(尤其是-v参数),看看它们是否对您有用。您只需像这样将它们放入您的管道中:
exec 4<&1 5<&2 1>&2>&>(tee -a | cat -v | $LOG_FILE)
By the way, almost all terminal programs have an option to capture the input, and most clean it up for you. What platform are you on, and what type of terminal program are you using?
顺便说一句,几乎所有终端程序都有一个选项来捕获输入,并且大多数会为您清理它。你在什么平台上,你使用什么类型的终端程序?
回答by Mattias Ahnberg
Might not screen -Lor the scriptcommands be viable options instead of this exec loop?
可能不是screen -L或者script命令是可行的选项而不是这个 exec 循环?
回答by Dennis
You could attempt to use the -n option for read. It reads in n characters instead of waiting for a new line. You could set it to one. This would increase the number of iteration the code runs, but it would not wait for newlines.
您可以尝试使用 -n 选项进行读取。它读入 n 个字符而不是等待换行。你可以把它设置为一个。这会增加代码运行的迭代次数,但不会等待换行。
From the man:
来自男人:
-n NCHARS read returns after reading NCHARS characters rather than waiting for a complete line of input.
-n NCHARS read returns after reading NCHARS characters rather than waiting for a complete line of input.
Note: I have not tested this
注意:我没有测试过这个
回答by sehe
You can use ANSIFilter to strip or transform console output with ANSI escape sequences.
您可以使用 ANSIFilter 剥离或转换带有 ANSI 转义序列的控制台输出。

