カラー出力(ls
またはなどgcc
)を印刷する端末からコマンドを実行すると、カラー出力が印刷されます。私の理解では、プロセスは実際にANSIエスケープコードを出力しており、端末は色をフォーマットしています。
ただし、別のプロセス(たとえば、カスタムCアプリケーション)で同じコマンドを実行し、出力をアプリケーションの独自の出力にリダイレクトすると、これらの色は持続しません。
プログラムは、テキストをカラー形式で出力するかどうかをどのように決定しますか?環境変数はありますか?
カラー出力(ls
またはなどgcc
)を印刷する端末からコマンドを実行すると、カラー出力が印刷されます。私の理解では、プロセスは実際にANSIエスケープコードを出力しており、端末は色をフォーマットしています。
ただし、別のプロセス(たとえば、カスタムCアプリケーション)で同じコマンドを実行し、出力をアプリケーションの独自の出力にリダイレクトすると、これらの色は持続しません。
プログラムは、テキストをカラー形式で出力するかどうかをどのように決定しますか?環境変数はありますか?
回答:
そのようなプログラムのほとんどは、デフォルトでは端末にカラーコードのみを出力します。を使用して、出力がTTYかどうかを確認しますisatty(3)
。通常、この動作をオーバーライドするオプションがあります。すべての場合で色を無効にするか、すべての場合で色を有効にします。たとえば、GNU grep
の場合、--color=never
色を無効にして--color=always
有効にします。
シェルでは、-t
test
演算子を使用して同じテストを実行できます[ -t 1 ]
。標準出力が端末の場合のみ成功します。
環境変数はありますか?
はい。これはTERM
環境変数です。これは、決定プロセスの一部として使用されるものがいくつかあるためです。
すべてのプログラムが単一の決定フローチャートに同意するわけではないため、ここで一般化することは困難です。実際grep
、M。Kittの回答で言及されているGNU は、予想外の結果を伴うやや異常な決定プロセスを使用する外れ値の良い例です。したがって、非常に一般的な用語では:
isatty()
。TERM
環境変数が存在している必要があり、その値は、データベースレコードと一致する必要があります。TERMCAP
環境変数を使用して指定できます。そのため、一部の実装では、2番目の環境変数があります。max_colors
terminfoにはフィールドがあります。実際にカラー機能を持たない端末タイプには設定されていません。実際、すべてのカラー表示可能な端末タイプには、カラー機能がないことを示す名前の付いた、-m
または-mono
名前に追加された別のレコードがあるというterminfoの規則があります。set_a_foreground
とset_a_background
フィールドがあります。単にチェックするよりも少し複雑ですisatty()
。それが行われ、さらにいくつかのことによって複雑に:
isatty()
チェックを無効にするコマンドラインオプションまたは構成フラグを追加します。これにより、プログラムは、出力として(色付け可能な)ターミナルがあると常にまたは決して想定しません。たとえば:
ls
には--color
コマンドラインオプションがあります。ls
見CLICOLOR
(その不在は意味ありません)とCLICOLOR_FORCE
(その存在は意味常に)環境変数、また、スポーツ-G
コマンドラインオプションを。TERM
。前述のように、GNUはgrep
実際にこれらの追加の複雑さのいくつかを示します。termcap / terminfoを参照せず、制御シーケンスを出力するように配線し、TERM
環境変数への応答を配線します。
それののLinux / Unixのポートは、このコードを持っている場合にのみ、色化を可能にする、TERM
環境変数が存在し、その値は、ハードワイヤードの名前と一致していませんdumb
。
int should_colorize(void) { char const * t = getenv( "TERM"); return t && strcmp(t、 "dumb")!= 0; }
ですから、たとえあなたTERM
がxterm-mono
であるとしても、GNU grep
は他のプログラムvim
はそうではないにしても、色を出すことを決定します。
それのWin32ポートにはこのコードがあり、TERM
環境変数が存在しない場合、または存在し、その値が配線された名前と一致しない場合に色付けを可能にしますdumb
:
int should_colorize(void) { char const * t = getenv( "TERM"); 戻ります!(t && strcmp(t、 "dumb")== 0); }
grep
の色に関する問題GNU grep
の色付けは実際には悪名高いです。実際には端末出力を構築する適切な仕事をしていませんが、出力のさまざまなポイントでいくつかのハードワイヤード制御シーケンスを非難するだけで、それが十分であることを望んでいないため、特定の状況で実際に誤った出力を表示します。
これらの状況は、端末の右端にある何かを色付けする必要がある場合です。端末出力を適切に行うプログラムは、自動右マージンを考慮する必要があります。 また、端末のかもしれないが、それらを持っていないというわずかな可能性に(VIZ auto_right_margin
のterminfo内のフィールド)、自動右マージンを持っていない端末の動作は、多くの場合の12月VTの先例次の行の折り返しを保留します。GNU grep
はこれを考慮せず、素直な行の折り返しを単純に期待しており、その色付き出力は間違っています。
カラー出力は単純なものではありません。
grep --color
正しい出力を表示しません」。xtermのよくある質問。目に見えない島。$TERM
それを説明しません。(あなたの答えは一般的に興味深いですが、私はそれが質問に対処するとは思わない...)