「lsのパイプ後も色が付く」の続きです。
color_indicatorの使用箇所を検索します。
takk@deb9:~/src/coreutils-8.26/src$ grep color_indicator ls.c static const struct bin_str * get_color_indicator (const struct fileinfo *f, static bool print_color_indicator (const struct bin_str *ind); static struct bin_str color_indicator[] = size_t len = color_indicator[type].len; char const *s = color_indicator[type].string; put_indicator (&color_indicator[C_LEFT]); put_indicator (&color_indicator[C_RIGHT]); put_indicator (&color_indicator[C_LEFT]); put_indicator (&color_indicator[C_NORM]); put_indicator (&color_indicator[C_RIGHT]); assert (ARRAY_CARDINALITY (color_indicator) + 1 if (!(color_indicator[C_LEFT].len == 2 && memcmp (color_indicator[C_LEFT].string, "\033[", 2) == 0 && color_indicator[C_RIGHT].len == 1 && color_indicator[C_RIGHT].string[0] == 'm')) color_indicator[ind_no].string = buf; &color_indicator[ind_no].len) if (color_indicator[C_LINK].len == 6 && !STRNCMP_LIT (color_indicator[C_LINK].string, "target")) print_color_indicator (color); get_color_indicator (f, symlink_target) : NULL; put_indicator (&color_indicator[C_CLR_TO_EOL]); if (color_indicator[C_END].string != NULL) put_indicator (&color_indicator[C_END]); put_indicator (&color_indicator[C_LEFT]); put_indicator (&color_indicator[C_RESET]); put_indicator (&color_indicator[C_RIGHT]); print_color_indicator (const struct bin_str *ind) put_indicator (&color_indicator[C_LEFT]); put_indicator (&color_indicator[C_RIGHT]); get_color_indicator (const struct fileinfo *f, bool symlink_target) = ext ? &(ext->seq) : &color_indicator[type]; takk@deb9:~/src/coreutils-8.26/src$
いろんな所で使われています。怪しいところは。。。
put_indicatorって関数でcolor_indicatorを使ってますね。put_indicatorを見てみることにします。
ls.c
4665 static void 4666 put_indicator (const struct bin_str *ind) 4667 { 4668 if (! used_color) 4669 { 4670 used_color = true; 4671 4672 /* If the standard output is a controlling terminal, watch out 4673 for signals, so that the colors can be restored to the 4674 default state if "ls" is suspended or interrupted. */ 4675 4676 if (0 <= tcgetpgrp (STDOUT_FILENO)) 4677 signal_init (); 4678 4679 prep_non_filename_text (); 4680 } 4681 4682 fwrite (ind->string, ind->len, 1, stdout); 4683 }
途中のコメントが興味深いですが、ここで確認するのは、fwriteを使ってるってところです。つまりlsで色(エスケープシーケンス)を出力する場合は、fwriteを使う、で良いかと思います。
対してgrepはどうだったかというと。。。。
ああ、そういえば、grepが本当にprintfを使っていたかは未確認でした。
引数に%sを与えてることからしてprintfを使ってるだろうと推測していましたが、一応確認してみましょう。
grep.c
308 static const char *sgr_start = "\33[%sm\33[K"; 309 static const char *sgr_end = "\33[m\33[K"; 310 311 /* SGR utility functions. */ 312 static void 313 pr_sgr_start (char const *s) 314 { 315 if (*s) 316 print_start_colorize (sgr_start, s); 317 }
print_start_colorizeを検索。
takk@deb9:~/src/grep-2.27$ grep print_start_colorize -r * ChangeLog: print_start_colorize, print_end_colorize from colorize.h. lib/colorize.h:extern void print_start_colorize (char const *sgr_start, char const *sgr_seq); lib/colorize-posix.c:print_start_colorize (char const *sgr_start, char const *sgr_seq) lib/colorize-w32.c:print_start_colorize (char const *sgr_start, char const *sgr_seq) src/grep.c: print_start_colorize (sgr_start, s); takk@deb9:~/src/grep-2.27$
lib/colorize-posix.cを確認。
45 /* Start a colorized text attribute on stdout using the SGR_START 46 format; the attribute is specified by SGR_SEQ. */ 47 void 48 print_start_colorize (char const *sgr_start, char const *sgr_seq) 49 { 50 printf (sgr_start, sgr_seq); 51 }
予想通りprintfでした。
lsは、fwrite。grepはprintf。これが色が付く付かないの理由なのでしょうか。
つづく
コメント