理系学生日記

おまえはいつまで学生気分なのか

Mac の apropos でエスケープシーケンスを正しく処理してくれない件

Spotlight の存在をものともせず,ぼくは apropos コマンドを使っていたんですけど,mac だとエスケープシーケンスの処理をうまくやってないみたいです.よっしゃ読みづらい!!

$ apropos base64
APR::ESC[01;31mBase64ESC[00m(3pm)         - Perl API for APR ESC[01;31mbase64ESC[00m encoding/decoding functionality
BIO_f_ESC[01;31mbase64ESC[00m(3ssl)       - ESC[01;31mbase64ESC[00m BIO filter
MIME::ESC[01;31mBase64ESC[00m(3pm)        - Encoding and decoding of ESC[01;31mbase64ESC[00m strings
MIME::Decoder::ESC[01;31mBase64ESC[00m(3pm) - encode/decode a "ESC[01;31mbase64ESC[00m" stream
MIME::Decoder::Gzip64(3pm) - decode a "ESC[01;31mbase64ESC[00m" gzip stream
ESC[01;31mbase64ESC[00m(n)                - Encoding "ESC[01;31mbase64ESC[00m" '" -*- tcl -*- doctools = trf_header.inc

ぼくはこれまでこの問題を放置していましたが,今日はちょっと気になったので,調べてみることにした.
問題はわりと簡単で,apropos は単なるシェルスクリプト.環境変数として PAGER を設定していないと,more を呼び出すらしい.

$ tail -3 /usr/bin/apropos
done | ${PAGER:-more -E}

exit

ちなみに同機能を有する whatis というコマンド(これもシェルスクリプト)についても,ほぼ全て apropos と同じなので,同様の問題が生じます.

$ diff /usr/bin/apropos /usr/bin/whatis
26,27c26,27
< grepopt1=$aproposgrepopt1
< grepopt2=$aproposgrepopt2
---
> grepopt1=$whatisgrepopt1
> grepopt2=$whatisgrepopt2

なるほどなるほど,じゃぁ less にすれば良いんじゃねとか思って,less を設定してやると確かにエスケープシーケンスを処理してくれるようになりました*1

$ PAGER=less apropos base64
APR::Base64(3pm)         - Perl API for APR base64 encoding/decoding functionality
BIO_f_base64(3ssl)       - base64 BIO filter
MIME::Base64(3pm)        - Encoding and decoding of base64 strings
MIME::Decoder::Base64(3pm) - encode/decode a "base64" stream
MIME::Decoder::Gzip64(3pm) - decode a "base64" gzip stream
base64(n)                - Encoding "base64" '" -*- tcl -*- doctools = trf_header.inc

しかし,実は less と more は互いに同じ i-node を有していたりする.

$ which more less
/usr/bin/more
/usr/bin/less
$ ll -i /usr/bin/more /usr/bin/less
63818 -rwxr-xr-x  2 root  wheel   248K  9 24  2007 /usr/bin/less*
63818 -rwxr-xr-x  2 root  wheel   248K  9 24  2007 /usr/bin/more*

同じプログラムなのにも関わらず,more ではなく less を起動すると問題が解決するということは,プログラム名で分岐してたりするんでしょうか.ソースを読めば分かるんだと思いますが,mac 付属のコマンドってソース公開してるんでしょうか?そのへんがよくわからない.

*1:実際には,下記の表示ではなく,一度ターミナルの表示がクリアされた後,base64 に関するエントリが表示される形です