zshはmacOSのデフォルトログインシェルである。多機能で便利なシェルであるが、ダム端末で使われることを想定していないようだ。この記事ではダム端末とはshellやコマンドの出力をそのまま表示する端末のこととしよう。Acme, 9term, Emacs shellなどはダム端末である。それに対してxtermやGNOME Terminal, Terminal.appはVT100をエミュレートしている端末で、出力に含まれるESC [
から始まるエスケープシーケンスによって文字色を変えたりする機能をもつ(この辺はよくわかってない。Wikipediaなどの情報を参照している)。xtermを想定した出力をダム端末に送ると、ダム端末はエスケープシーケンスを解釈できず、エスケープシーケンスがそのまま奇妙な文字列として表示されてしまうのである。zshをデフォルト設定で用いると出力されるエスケープシーケンスによってAcmeやEmacsの表示が崩れる。
acmeユーザーならシェルにrc(1)を使うだろう(私も同様)から、誰がこの記事を参照するんだろう?
解決策
次のソースを$HOME/.zshrc
に書けばOK
if [ "$TERM" = dumb ] then unsetopt ZLE unsetopt PROMPT_CR export PS1='%0~ %# ' export PAGER='col -xb' export EDITOR='ed' fi
解説
現在の端末がダム端末かどうか調べるには環境変数TERM
を確認すれば良い。
Zsh Line Editor (ZLE)
ZLEはreadlineみたいな機能を提供してると思われる。こいつがむちゃくちゃな出力をする元凶。オフ。
PROMPT_CR
xterm上の端末ではzshは出力の最後に改行がついていない場合、%
を出力して自動的に改行する。ダム端末では最後に改行がついてるかどうか判別できず、常に末尾に%
をつけてくる。
環境変数
PS1
文字の色がないプロンプトにする必要がある。端末の文字色はエスケープシーケンスによって制御しているからだ。色がつかなければ何でもよい。
PAGER
通常はman(1)やgit(1)はless(1)を起動して出力を表示する。しかしながらダム端末ではlessなど動かない。これらのコマンドは環境変数PAGER
が設定されているとlessの代わりに$PAGER
を起動して表示する。col(1)はエスケープシーケンスを削除してくれるコマンドである。manの出力にはタイトルや強調に使うエスケープシーケンスが含まれているのでそれらを削除する。colの代わりにcatを用いるとエスケープシーケンスが削除されずにダム端末によっては表示されてしまう。
lessみたいに行を少しずつ表示をしたければBrian W.Kernighan, Rob Pikeの「Unixプログラミング環境」に紹介されているpを使えば良い。plan9portにも提供されている。このソフトウェアはエスケープシーケンスを使っていないので正常に動作する。
EDITOR
ダム端末ではviなどのスクリーンエディタは利用できない。コマンドによってはエディタが不意に起動する場合もあるので、スクリーンエディタが起動できないようにすること。ここではedとした。
参考になる文献
xtermのエスケープシーケンスについて www.xfree86.org
過去のPOSIXにあったcolコマンド(今は削除されたみたい) pubs.opengroup.org