私は大きな台本を書いた。スクリプトはうまくいきますが、私が経験している問題はリダイレクトです。ログファイルにリダイレクトするために、次のブロックを実行しました。
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スクリプトはここで最高です。
スクリプトから印刷されたメッセージにのみ興味がある場合は、標準出力とログファイルにメッセージを印刷し、後者からカラーコードを削除する関数を作成できます。ただし、これはコマンド出力を同じログファイルに保存するのには役立ちません。