結果をバイナリファイルとして記録するためのカラー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行うには、stdoutとパイプから出力を取得する必要があるため、完全に単純ではありません。サブシェルリダイレクトトリックよりも良い方法があるかもしれません。これは 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"

Linuxで再度開くときの影響を防ぐためのシェルのもう1つのオプションは次のとおりです。/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良い候補ツールです。

関連情報