2013年07月01日

ログインシェルをzshに換えた

Mac OS XのCLI環境の整備を本格的に始めた。プログラム開発環境をCLIに統合化することがこの作業の最終目的。前記事で紹介したとおり、プログラミングエディタをMacVimに換えたこともこの目的の一部だ。Vimの導入に続く第二段の作業として、ターミナルのログインシェルをzsh(Z Shell)に換えたので、備忘録を兼ねてその作業ログを書いていく。

zshの特徴についてはWikipediaのこちらのページに詳しく書かれているので説明は省略するが、一度zshを使い始めると、他のものに変える気にならないほどの超優れ物のシェルらしい。zshの最大の特徴は強力な補完機能を備えていることで、この機能によって、少ない文字入力で目的のコマンドを生成することができる。zshの補完機能はプログラムによって記述されているので、ユーザがカスタマイズしたり追加することも可能。他にも多くの機能を備えていて、現状最強のシェルがzshだと言っても過言ではないだろう。Macを使い始めた頃からzshのことは知っていて、いつかシェルをこれに換えようと思っていながらついつい先延ばしにしてきた。本格的なCLI環境を構築するにあたって、まずはzshのインストールと設定作業から取りかかった。

■zshをインストールする


Mac OS Xにはデフォルト状態でzshが存在するが(/bin/zshがそれ)、バージョンが結構古い。最新版を使いたいなら、Homebrewによってインストールした方が良い。まずは、いつものようにzshのフォーミュラ情報を調べてみた。
$ brew info zsh
zsh: stable 5.0.2
http://www.zsh.org/
Not installed
From: https://github.com/mxcl/homebrew/commits/master/Library/Formula/zsh.rb
==> Dependencies
Required: gdbm, pcre
==> Options
--disable-etcdir
Disable the reading of Zsh rc files in /etc
==> Caveats
To use this build of Zsh as your login shell, add it to /etc/shells.

If you have administrator privileges, you must fix an Apple miss
configuration in Mac OS X 10.7 Lion by renaming /etc/zshenv to
/etc/zprofile, or Zsh will have the wrong PATH when executed
non-interactively by scripts.

Alternatively, install Zsh with /etc disabled:
brew install --disable-etcdir zsh

Add the following to your zshrc to access the online help:
unalias run-help
autoload run-help
HELPDIR=/usr/local/share/zsh/helpfiles

If you have administrator privileges, ...」で始まる注意書きメッセージが気になったので、これについてググってみた。すると、これは「Mac OS X Lionでは/etc/zshenvの内容に不具合があり、これによって、zsh起動時に環境変数PATHの設定値がリセットされる」ということを意味しているらしいことが判った。上のメッセージの説明のとおり、この問題の対処方法として次の2つがあるそうだ。
  1. /etc/zshenv/etc/zprofileにリネームする。
  2. brew install --disable-etcdir zsh」で、zshをインストールする。

私はAの方法を選択することに決めた。その前に、zshのインストールを先に行った。
$ brew install zsh

続いて、上記の問題の対処方法Aを実行した。
$ sudo mv /etc/zshenv /etc/zprofile


■ログインシェルをzshに設定する


これでzshがインストールできたので、さらに続いて、ログインシェルをzshに変更するための設定を行った。まずは、/etc/shellsを次のように編集した(一番最後に/usr/local/bin/zshを追加)。
$ sudo vi /etc/shells
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
/usr/local/bin/zsh

これはシェルのパス一覧を保持しているファイルで、Mac OS Xではこの中に定義されているシェルしか選択できないようになっている。ここまでの設定が済んだ状態で下のコマンドを実行すれば、ログインシェルはzshに変更される。
$ chpass -s /usr/local/bin/zsh

試しに新しいターミナルを開いてみた。すると、下のような画面が表示された。zshがログインシェルになっているのは、ウィンドウのタイトルに「ターミナル -- zsh」と表示されていることで確認できる。
Terminal-zsh-newuser-install-ScrnShot07-699x480
ホームディレクトリにzshの起動設定ファイルが一つも存在しないと、上の画面のメッセージが表示されるようだ。これらのファイルの設定例はググればたくさん見つかるので、後で自分で編集することにして、取りあえず、この画面では「0」を選択して空の.zshrcを作成しておいた。

■.zshrcを作成する


続いて、.zshrcの編集を行った。下がその内容。
export LANG=ja_JP.UTF-8

# Zsh ヒストリの設定
HISTFILE=~/.zsh_history
HISTSIZE=1000000
SAVEHIST=1000000

########################################
# Zsh 補完

# 補完機能を有効にする
autoload -Uz compinit
compinit

########################################
# Zsh オプション

# ディレクトリ名だけでcdする
setopt auto_cd

# cd したら自動的にpushdする
setopt auto_pushd

# 日本語ファイル名を表示可能にする
setopt print_eight_bit

上は必要最低限の設定だけしか記述していない。zshは非常に多くの機能を備えているので、今後この.zshrcにどんどん新しい設定を追加していくことになるだろう。

zshのインストールと起動設定が済んだので、さっそく新しいターミナルを開いてzshを使ってみた。zshのプロンプトに対して「ls <TAB>」と入力すると、補完機能が働いて、ディレクトリ名の候補一覧が自動的に表示される。
Terminal-zsh-File_Name_Completion-ScrnShot08-699x480
Terminal-zsh-File_Name_Completion-ScrnShot09-699x480
この状態で再度<TAB>を入力すると、上のように、1番目の候補のファイル名が「ls 」以降(<TAB>を入力した位置)に追加される。さらに<TAB>を入力すると、次の候補のファイル名に順番に変わっていく。

zshの補完機能は、ファイル名だけでなく、コマンド名、シェル変数や環境変数名、ユーザやホスト名、プロセスやジョブ名などにも対応している。さらに、入力済みのコマンドの文脈から適切な候補を検索する機能まで備えている。うろ覚えで途中までコマンドを入力してとにかく<TAB>を打ち続ければ、zshがどんどん候補を表示してるので、それらを適切に選択しながら辿っていくことで目的の完全なコマンドに到達することができる。実際に使い始めて、zshの補完機能のすばらしさをすぐに実感することができた。いままで「もはやzshなしではMacやLinuxを使う気になれない」と書いているページを多く見かけたが、この意見にもすぐに納得できた。こんなに便利なら、もっと早くzshを導入しておけば良かった。

■zsh-completionsをインストールする


これでzshのインストールと設定は完了だが、zshについてググっていると、いくつかの非標準コマンドの補完情報をまとめたzsh-completionsというものが存在することを知った。zsh自体に標準的なコマンドの補完情報は付属しているが、zsh-completionsをインストールすると、さらに、ackやgithubなどいくつかのコマンドで補完が使えるようになるらしい。これには「brew」コマンドの補完情報も含まれているので、Homebrewを使っているならぜひインストールするべきだ。zsh-completionsもHomebrewでインストールすることができるので、フォーミュラ情報を調べてみた。
$ brew info zsh-completions
zsh-completions: stable 0.9.0, HEAD
https://github.com/zsh-users/zsh-completions
Not installed
From: https://github.com/mxcl/homebrew/commits/master/Library/Formula/zsh-completions.rb
==> Caveats
To activate these completions, add the following to your .zshrc:

fpath=(/usr/local/share/zsh-completions $fpath)

You may also need to force rebuild `zcompdump`:

rm -f ~/.zcompdump; compinit

Additionally, if you receive "zsh compinit: insecure directories" warnings when attempting
to load these completions, you may need to run this:

chmod go-w /usr/local/share

上のフォーミュラ情報に含まれる注意書きメッセージをしっかりと読んだ上で、zsh-completionsのインストールを行った。
$ brew install zsh-completions

上の注意書きメッセージのとおり、zsh-completionsはインストールしただけでは有効にならない。zsh-completionsに収納されている補完情報を有効にするには、以下の設定を.zshrcに追加する必要がある(この設定は、.zshrc内に記述されている「autoload -Uz compinit; compinit」コマンドより前に置くこと)。
fpath=(/usr/local/share/zsh-completions $fpath)

さらに、次のコマンドを実行して、zshの補完情報の再構築も行わなければならない。
$ rm -f ~/.zcompdump
$ compinit

上の2つの操作を行った後ターミナルを再起動すると、下のような警告メッセージが表示された。
zsh compinit: insecure directories, run compaudit for list.
Ignore insecure directories and continue [y] or abort compinit [n]?

この警告メッセージを回避するには、.zshrc内の「compinit」コマンドに「-u」オプションをつければ良いそうだ。
compinit -u

zsh-completionsのインストールと設定がすべて終わったら、ターミナルを再起動すれば、「brew <Tab>」という入力したときに補完が働いて、下のようにサブコマンドの一覧が表示されるようになる(zsh-completionsをインストールする前は、「brew <Tab>」と入力しても、カレントディレクトリのファイル一覧が候補として表示されていた)。
Terminal-zsh-brew_Command_Completion-ScrnShot10-699x606
zsh-completionsに含まれている補完情報の一覧は、「ls /usr/local/share/zsh-completions」で確認することができる。このディレクトリには100個弱の「_」で始まるファイルが含まれているが、zshの非標準コマンドの補完情報を格納したファイルは「_<COMMAND>」という名前で作成する決まりになっている。

タグ:Mac OS X zsh
posted by とみやん at 13:18| Comment(4) | TrackBack(0) | PC > Mac
この記事へのコメント
とみやんさん、はじめまして。
最近僕もMacの/usr/bin/にデフォルトで入ってるzsh4.3.11からHomebrewで最新のzsh5.0.2に変更してみたんですが、シェルに日本語を入力すると勝手に変換される現象が起こるんですがとみやんさんはどうでしょうか?よかったら教えてください
Posted by はやぶさ at 2013年07月08日 05:53
はやぶささん、こんにちは。

ご質問の件ですが、私の環境では特に問題ないようです。

ローマ字入力だと、次のような動作になりますが、これは正常ですよね。

 「nihongo」→「にほんご」(自動変換)→<Space>→変換候補表示→<Tab>→候補選択→<Space>→候補確定

ちなみに、確認した動作環境は以下のとおりです。

 キーボード:MacBook Air 11" 搭載キーボード
 OS:Mac OS X Lion 10.7.5
 入力ソース:ことえり(ローマ字入力)
 ターミナル:Terminal.app(標準のターミナル)
 ログインシェル:zsh 5.0.2

ちなみに、普段私はGoogle日本語入力をかな入力に設定して使っていますが、こちらでも特に問題は発生していません。

そちらの動作環境や具体的な現象について詳細情報を教えていただけないでしょうか。そうすれば、こちらでも再度検証できるかと思います。
Posted by とみやん at 2013年07月10日 16:09
返信ありがとうございます。

ちゃんと動くんですね、羨ましいです。

僕の環境だと
「候補変換で"日本語"にカーソル合わせる」-> 「エンターで確定」-> 「日本語部分がよくわからないコードに変換される」->「それをechoなどで出力した場合、ちゃんともとの日本語が表示される」
という結果になるんですよね。
主に環境で違うところと言えばMacOSX10.8.4というところですかね。他にも日本語関係?でバグあったりするらしいですし可能性はありそうです。

一応zsh5.0移行に思いいれがあるわけがないので、ちゃんと動く4.3.15にバージョン下げて解決しました。

ありがとうございました。
Posted by はやぶさ at 2013年07月11日 11:33
はやぶささん

現象からの単純な推測とアドバイスですが・・・。

 (1) ターミナルのフォントが(漢字コードを含まない)欧文フォントに設定されているこということはありませんか。
 (2) zshの依存フォーミュラgdbm, pcreをインストールし直してみたらどうでしょう。

通常Terminal.appのフォントはMonacoかMenlo Reguarに設定されているみたいですが・・・。

以下の環境のMac miniでも検証してみましたが、こちらでは正常な動作をしています。

 キーボード:Apple Wireless Keyboard (US配列)
 OS:OS X Lion 10.8.3
 入力ソース:ことえり(ローマ字入力)
 ターミナル:Terminal.app(標準のターミナル)
 ログインシェル:zsh 5.0.2

ブロードバンド回線が低速なので、10.8.4への更新はまだやっていません。

ちなみに、Xcodeは4.2.1(MacBook Air)と4.6.3(Mac mini)です。

相違点があるとすれば、以下の点くらいでしょうか。

 ・キーボード(こちらはいずれもUS配列)
 ・Mac OS Xのバージョン
 ・Xcode or Command Line Toolsのバージョン

tmuxやoh-my-zshとかをzshと組み合わせて使う場合、4.3系より5.0系の方が互換性が高いのではないかと思います。

そちらの環境で何とかzsh 5.0.xが正常に動くと良いですね。
Posted by とみやん at 2013年07月13日 19:50
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/70293394

この記事へのトラックバック