彩色 Printf 重定向以将结果记录在二进制文件中

彩色 Printf 重定向以将结果记录在二进制文件中

我已经写了一个很大的剧本了。该脚本运行良好,我遇到的问题是重定向。我已经完成了以下块以重定向到日志文件:

log_location=/home/admin
exec > >(tee -i $log_location/health-check.log)
exec 2>&1
echo -e "Output will be saved at $log_location/health-check.log\n"

该脚本具有以下颜色:

G="\033[32m"
N="\033[0m"
R="\033[31m"
Y="\033[33m"

此控制台输出以彩色格式打印所需字符。但是,当我减少 .log 文件时,它最终会变成二进制文件,并且在查看时我会看到如下内容:

ESC[33mGSANESC[0m Service Status is              |ESC[32mUPESC[0m
ESC[33mMCSESC[0m Service Status is               |ESC[32mUPESC[0m
ESC[33mTomcatESC[0m Service Status is    |ESC[32mUPESC[0m
ESC[33mSchedulerESC[0m Service Status is         |ESC[31mDOWNESC[0m
ESC[33mMaintenanceESC[0m Service Status is       |ESC[31mSUSPENDEDESC[0m

我不介意日志文件中有非彩色输出。我有办法完成这件事吗?

答案1

我们可以安排sed从日志文件的输出中去除颜色代码。尽管这需要将输出从tee标准输出和管道获取,所以这并不完全简单。可能有比子 shell 重定向技巧更好的方法。这似乎适用于 Bash 和 GNU sed,stdout 得到红色error,日志文件没有颜色代码:

#!/bin/bash
exec > >( (tee -a /dev/fd/7 | sed -Ee $'s/\033''\[[0-9][0-9]?m//g ' > logfile) 7>&1 )
N=$'\033[0m'
R=$'\033[31m'
echo "${R}error${N}: foo"

shell 中的另一个选项可以避免在 Linux 上重新打开时产生的影响:/dev/fd/N

#!/bin/bash
exec > >(
        exec 7>logfile
        while IFS= read -r x ; do 
                echo "$x"
                x=${x//$'\033'\[[0-9]m}
                x=${x//$'\033'\[[0-9][0-9]m}
                echo "$x" >&7
        done    
)
N=$'\033[0m'
R=$'\033[31m'
echo "${R}error${N}: foo"

虽然这当然有 NUL 字节的问题,但日志输出可能没有很多这样的问题。也许 Perl 脚本在这里是最好的。

如果您只关心从脚本打印的消息,则可以创建一个函数将消息打印到标准输出和日志文件,并从后者中去除颜色代码。但这无助于将命令的输出保存到同一个日志文件中。

答案2

您可以使用sed/ awk/... 过滤器在基于管道重定向的日志中去除颜色定义tee(如前面的答案所建议),

...或者简单地生成无色日志输出并让日志可视化工具本身处理着色:例如,multitail是一个很好的候选工具。

相关内容