lsのパイプ後も色が付く

4-3.文字列置換

grepの色付きの結果をパイプでtailに渡すと色が消えました。

takk@deb9:~/tmp/gmp-6.1.2+dfsg$ grep -r In.general --color | tail -3

lsではどうでしょうか。

takk@deb9:~/tmp/gmp-6.1.2+dfsg$ ls --color

–colorをつけてlsを実行すると各ファイルに応じた色が付きますが、
tailに渡すと、

takk@deb9:~/tmp/gmp-6.1.2+dfsg$ ls --color | tail -3


あれれ、こちらは色が付くんですね。
grepとの違いは何でしょう。

lsのソースを見てみます。coreutilsのソースを取得したら、エスケープの番号である33がls.cに存在するか確認してみます。

takk@deb9:~/src/coreutils-8.26/src$ grep 33 ls.c
    { LEN_STR_PAIR ("\033[") },         /* lc: Left of color sequence */
    { LEN_STR_PAIR ("33") },            /* pi: Pipe: yellow/brown */
    { LEN_STR_PAIR ("01;33") },         /* bd: Block device: bright yellow */
    { LEN_STR_PAIR ("01;33") },         /* cd: Char device: bright yellow */
    { LEN_STR_PAIR ("\033[K") },        /* cl: clear to end of line */
         when left is "\033[" and right is "m".  */
            && memcmp (color_indicator[C_LEFT].string, "\033[", 2) == 0
takk@deb9:~/src/coreutils-8.26/src$

ヒットしましたね。 やはりlsも、エスケープシーケンスで色を付けているで間違いないですね。

ではこれを定義している配列を確認してみます。

   596  static struct bin_str color_indicator[] =
   597    {
   598      { LEN_STR_PAIR ("\033[") },         /* lc: Left of color sequence */
   599      { LEN_STR_PAIR ("m") },             /* rc: Right of color sequence *
   600      { 0, NULL },                        /* ec: End color (replaces lc+rs
   601      { LEN_STR_PAIR ("0") },             /* rs: Reset to ordinary colors
   602      { 0, NULL },                        /* no: Normal */
   603      { 0, NULL },                        /* fi: File: default */
   604      { LEN_STR_PAIR ("01;34") },         /* di: Directory: bright blue */
   605      { LEN_STR_PAIR ("01;36") },         /* ln: Symlink: bright cyan */
   606      { LEN_STR_PAIR ("33") },            /* pi: Pipe: yellow/brown */
   607      { LEN_STR_PAIR ("01;35") },         /* so: Socket: bright magenta */
   608      { LEN_STR_PAIR ("01;33") },         /* bd: Block device: bright yell
   609      { LEN_STR_PAIR ("01;33") },         /* cd: Char device: bright yello
   610      { 0, NULL },                        /* mi: Missing file: undefined *
   611      { 0, NULL },                        /* or: Orphaned symlink: undefin
   612      { LEN_STR_PAIR ("01;32") },         /* ex: Executable: bright green
   613      { LEN_STR_PAIR ("01;35") },         /* do: Door: bright magenta */
   614      { LEN_STR_PAIR ("37;41") },         /* su: setuid: white on red */
   615      { LEN_STR_PAIR ("30;43") },         /* sg: setgid: black on yellow *
   616      { LEN_STR_PAIR ("37;44") },         /* st: sticky: black on blue */
   617      { LEN_STR_PAIR ("34;42") },         /* ow: other-writable: blue on g
   618      { LEN_STR_PAIR ("30;42") },         /* tw: ow w/ sticky: black on gr
   619      { LEN_STR_PAIR ("30;41") },         /* ca: black on red */
   620      { 0, NULL },                        /* mh: disabled by default */
   621      { LEN_STR_PAIR ("\033[K") },        /* cl: clear to end of line */
   622    };

LEN_STR_PAIRのマクロは何をやってるのでしょうか。使用されていない行、たとえば620行目を見ると、パラメータが2つありますので、長さと文字列のポインタを表していると思います。マクロの名前そのままの意味でした。
次回は、このテーブルの変数、color_indicatorの使用箇所を見ていきます。

コメント

タイトルとURLをコピーしました