エンジニアにシェルのカスタマイズを勧めると「自分はあまりシェルコマンドが得意ではないから」と敬遠されがちである。だが、そのようなエンジニアこそシェルにこだわってほしい。インタラクティブシェルはシェル作業における基礎となるツールであり、我々のシェル作業をサポートしてくれるものである。シェルコマンドが苦手だからこそシェルをカスタマイズするべきなのだ。
有名なシェルの 1 つであり zsh と呼ばれることが多い。この記事でも以下 zsh と呼ぶことにする。
macOS や Ubuntu を含むほとんどの OS のデフォルトシェルは bash である。 bash, zsh は共に POSIX に準拠しており、bash で動くコマンドやスクリプトの多くは zsh でも動くようになっている。
他に有名なシェルとして fish がある。
zsh の優れている点をいくつか紹介する。
macOS など、最初から zsh がインストールされている OS もある。
which zsh
で zsh の場所を確認することができる。
macOS ではプリインストールの zsh のバージョンが最新ではないかもしれない。その場合は Homebrew を使って最新版の zsh をインストールしてもよい。
brew install zsh
ログインシェルは、Linux ユーザとしてログインした後にユーザセッションとして開始されるシェルプログラムである。
macOS では、初期設定のターミナルアプリで新しいセッションを開始すると自動的にログインシェルが実行されるようになっている。
まず、ログインシェルに設定するシェルの実行可能ファイルは /etc/shells
に列挙されている必要がある。
/etc/shells
を編集するには root 権限が必要なので、以下のようなコマンドで zsh の実行可能ファイルまでの絶対パスを /etc/shells
のファイル末尾に追記する。
which zsh | sudo tee -a /etc/shells >/dev/null
次にログインしているユーザのログインシェルを変更する。
chsh -s "$(which zsh)"
ログインシェルの設定を完全に反映するために、このコマンドを実行した後に一度ログアウトすることが好ましい。
zsh の設定ファイルは複数存在する。 設定ファイルによって読み込まれる条件やタイミングも異なるので、目的に合致する設定ファイルを考える。
zsh が一番最初に読み込む設定ファイル。
環境変数の設定を記述することが多いが ~/.zshenv
に記述した環境変数は zsh プログラム自体にも影響を与える。通常 ~/.zshenv
では以下の環境変数を設定する。
環境変数 | 説明 |
---|---|
LANG | デフォルトのロケールカテゴリ |
ZDOTDIR | 後節で説明 |
ログインシェルとして起動された ( -l
オプションが引数に与えられた) 場合に読み込む設定ファイル。
Linux 環境ではログイン時に, macOS 環境ではターミナルアプリでセッションを開始する度に読み込まれる。
基本的に export する環境変数を記述する。 ( PATH
など)
インタラクティブシェルとして起動された ( -i
オプションが引数に与えられた) 場合に読み込む設定ファイル。
ほとんどのカスタマイズ設定は ~/.zshrc
に記述することになる。
ZDOTDIR
を設定してホームディレクトリをスッキリさせるzsh は設定ファイルが 3 つも存在するのでホームディレクトリ直下がゴチャっとしてしまう。
~/
├ .zprofile
├ .zshenv
└ .zshrc
ZDOTDIR
という環境変数を設定すると ~/.zprofile
, ~/.zshrc
をホームディレクトリ以外のディレクトリに配置できる。
export ZDOTDIR=~/.zsh
ただし下記の 2 点に注意する。
ZDOTDIR
は zsh に対する環境変数なので zshenv
に設定を記述する( ~/.zprofile
, ~/.zshrc
を読み込む時点で定義済みでないと意味がない)
既に ZDOTDIR
を export している zsh 上で zsh を実行した場合 zshenv
は ${ZDOTDIR}/.zshenv
を参照してしまうので、念の為 symlink を定義しておく
# ZDOTDIR=~/.zsh
ln -fs ~/.zshenv ~/.zsh/.zshenv
これでホームディレクトリ直下が少しスッキリする。
~/
├ .zsh/
│ ├ .zprofile
│ ├ .zshenv -> ~/.zshenv
│ └ .zshrc
└ .zshenv
インストール時に自動的に bash の設定を追加する開発ツールは多い。主に
といった内容の設定がインストーラによって追加されることが多い。
それらの設定が存在する場合、それらを zsh の設定ファイルに移行しなければ今まで使っていた開発ツールは正しく動作しない。 以下のファイルをチェックして、必要な設定は zsh に移行する。
/etc/bash_profile
/etc/bashrc
~/.bash_profile
~/.bashrc
bash と zsh はコマンド補完の定義の方法が異なる。
zsh で bash のコマンド補完定義を解釈したい場合は bashcompinit
を使う。
autoload -Uz bashcompinit && bashcompinit
基本的に bash のコマンド補完と比べ zsh ネイティブなコマンド補完の方が機能的に優れていることが多い。 今まで使っていた bash のコマンド補完をそのまま移行する前に、後述する zsh-completions に zsh ネイティブなコマンド補完が存在していないか確認しよう。
zsh のプラグインを管理するプラグインマネージャとして zinit をオススメする。
zinit の優れている点をいくつか紹介する。
Oh My Zsh は zsh プラグインマネージャと zsh プラグインのセットである。
今回はプラグインマネージャとして zinit を紹介したが zinit で Oh My Zsh のプラグインを管理することもできる。
# ohmyzsh/ohmyzsh/lib -> OMZL
zinit snippet OMZL::clipboard.zsh
# ohmyzsh/ohmyzsh/plugins -> OMZP
zinit snippet OMZP::zsh_reload/zsh_reload.plugin.zsh
sorin-ionescu/prezto: The configuration framework for Zsh
Prezto も Oh My Zsh と同じく zsh プラグインマネージャとモジュールのセットである。 Oh My Zsh より後発であり、全てのモジュールが極力遅延ロードされるように設計されている。
zinit で Prezto のモジュールを管理することもできる。
# sorin-ionescu/prezto -> PZT
zinit ice svn
zinit snippet PZT::modules/gnu-utility
コマンド履歴をファイルに書き出すことで、異なるセッションでコマンド履歴を共有することができる。
# ZDOTDIR=~/.zsh
HISTSIZE=10000
HISTFILE="${ZDOTDIR}/.zsh_history"
SAVEHIST=10000
環境変数 | 説明 |
---|---|
HISTSIZE | 内部コマンド履歴に保存するコマンド履歴の最大数 |
HISTFILE | インタラクティブシェルが終了したときにコマンド履歴を保存するためファイル |
SAVEHIST | 履歴ファイルに保存するコマンド履歴の最大数 |
参考: zshparam(1)
zdharma/history-search-multi-word: Multi-word, syntax highlighted history searching for Zsh
zsh は control-R でコマンド履歴を検索できるが、前方一致の検索しか存在せず使いづらい。 history-search-multi-word は複数ワードをサポートするコマンド履歴検索機能の再実装である。以前使ったコマンドが思い出せないときに、覚えている箇所からすぐ検索できるので大変重宝する。
zinit ice wait'1' lucid
zinit light -b zdharma/history-search-multi-word
入力したコマンドが見やすくハイライトされる。 前節で紹介した history-search-multi-word で検索したコマンド履歴もハイライトされるので大変見やすい。
zinit ice wait atinit'zpcompinit; zpcdreplay' lucid
zinit light zdharma/fast-syntax-highlighting
zsh ではコマンド補完の挙動を強力にカスタマイズできる。 利用可能な設定は zshcompsys(1) で参照できるが、私でも全てを把握しきれていないほど数が多いので Oh My Zsh の「コマンド補完の挙動をいい感じにしてくれるライブラリ」を読み込む。
ohmyzsh/completion.zsh at master · ohmyzsh/ohmyzsh
zinit snippet OMZL::completion.zsh
コマンド補完定義の詰め合わせパック zsh-completions の導入もオススメする。 zsh-completions はコマンド補完の定義が遅延ロードされるように設計されているため、普段使わないコマンド補完の定義が含まれていても気にすることはない。
zsh-users/zsh-completions: Additional completion definitions for Zsh.
zinit ice pick'' blockf wait''
zinit light zsh-users/zsh-completions