標準エラー出力に色を付けて標準出力と区別しやすいようにするには 2015/04/21
結論を先に書くと、以下のようにするがいまのところよさそうである。
(foobarcmd; 2>&1 >&3 | perl -npe 'BEGIN {$|=1} s/^(.*)$/\e[31m$1\e[m/' >&2) 3>&1
foobarcmd
のところに任意のコマンドを書く。
このスクリプトの組み立て方。
まず、色をつけるにはエスケープシーケンスを各行に付ければよくて、それをPerlのワンライナーでパイプ処理することにする。 Perlでなくてもなんでもいいとは思うが、Perlならどこの環境にもあると思うので。
エラー出力のみをパイプ処理するには、以下のような感じにしてみる。
(foobarcmd; 2>&1 >&3 | PERLONELINER >&2) 3>&1
コマンドのエラー出力をパイプに渡すために 2>&1
を付けて、標準出力は次のPerlワンライナーを通さないようにするために >&3
として別のファイル記述子にリダイレクトする。
2>&1
と >&3
の順番を入れ替えると上手く動かない。
Perlワンライナーが処理した結果は本来標準エラー出力に出したいので、>&2
としてPerlの出力をエラー出力にリダイレクトする。ここまでを括弧で囲んだ上で、ファイル記述子3
にリダイレクトしていた出力を本来の標準出力に戻すために 3>&1
と書く。
次にPerlワンライナーを書くが、行頭に色を付けるエスケープシーケンスを付けて、行末にそれをリセットするエスケープシーケンスを付ければよいので、各行で s/^(.*)$/\e[31m$1\e[m/
という置換をする。従って以下のようになる。
(foobarcmd; 2>&1 >&3 | perl -npe 's/^(.*)$/\e[31m$1\e[m/' >&2) 3>&1
perlのオプションの -n
は入力各行に対してワンライナーを実行するという意味。
-p
は各行に対して実行した後に $_
つまり置換処理を実行した結果を表示するという意味。
-e
はPerlスクリプトをその後のコマンドラインで与えるとい、ワンライナーに必須のオプション。
これでもいちおう動くが、perlが出力をバッファリングしてしまうので、それを解除するためにワンライナーの先頭に BEGIN {$|=1}
と書く。
(foobarcmd; 2>&1 >&3 | perl -npe 'BEGIN {$|=1} s/^(.*)$/\e[31m$1\e[m/' >&2) 3>&1
これでできあがり。