zsh
The most powerful shell
Installation
基本的にはOSに入ってる /bin/zsh を使う。
新しいのを入れるならHomebrewを使うのが楽:
brew install zsh
brew install zsh-completions
Configuration files
https://zsh.sourceforge.io/Doc/Release/Files.html
$ZDOTDIR 以下の個人設定ファイルが場合に応じて下記の順で読まれる。
システム全体の設定ファイルとして /etc/z* が個人設定ファイルの前に読み込まれる。
/etc/zshenv- スクリプトの実行時も含めてあらゆる場合に読み込まれ、オプションでも外せない。
Ubuntuはここで基本的な
PATHを設定。 .zshenv- スクリプトの実行時も含めてほぼあらゆる場合に読み込まれる。
インタラクティブ用の設定などはせず、最低限の記述に留める。
例えば
ZDOTDIR,unsetopt NOMATCHなど。 - ここで
PATHを設定したい気もするけど、 OSによっては次の/etc/zprofileで上書きされてしまう。unsetopt GLOBAL_RCSとしてそれを防ぐ手もあるけどやや危険。 /etc/zprofile- Macでは
/usr/libexec/path_helperが/usr/binなどの基本的なPATHを設定する。 - ここで
/etc/profileをsourceして設定するLinuxもある。 .zprofile- ログインシェルとして立ち上げるときのみ読まれる。
exportする環境変数(PATHとか)を設定するのに適している。.bash_profileとの共通設定を.profileに書いておいてsourceするとか。 - 例えばローカル環境Mac + リモート環境Linux CUIで開発する場合、
ターミナルもtmuxもデフォルトでログインシェルを立ち上げるので、
.zshrcに一本化してしまっても構わない。 - 使い分けるのはLinux GUIを使う場合とか、 よほど重い初期化をログインシェル1回で済ませたい場合とか。
.zshrc- ログイン・非ログイン問わず、インタラクティブシェルとして立ち上げるときに読まれる。 こだわりが無ければだいたいどの設定もこれに書いておけば問題ない。
.zprofileと使い分けるならsetoptやautoloadなど、親シェルから引き継がれないものはこちら。aliasなどは別ファイルを読み込む形にして.bashrcと共有。.zlogin.zshrcより後に読まれる以外は.zprofileと同じ。使わない。.zlogout- ログアウト時にしてほしいことが万が一あれば。
以下は Bash の設定ファイル。 https://www.gnu.org/software/bash/manual/bash.html#Bash-Startup-Files
/etc/profile- ログインシェルの場合ここから開始。
- OSによって
/etc/bash.bashrcや/etc/bashrcをsourceする。 ~/.bash_profile- ログインシェルの場合の2つめ。
もし存在しなかったら
~/.bash_loginを読みに行き、 それも存在しなかったら~/.profileを読む。 どれかが読めたところで自動読み込みは終了。 つまりこれが存在する場合は~/.profileが自動では読み込まれないし、 いずれにせよ~/.bashrcを自動で読みには行かない。 - ほかのシェルとの共通設定を
~/.profileと~/.bashrcに書き、 ここではそれらをsourceするだけにしておくと見通しがいい。 ~/.bashrc- 非ログインでインタラクティブの場合に自動で読まれる唯一のファイル。
- ログインシェルの場合は自動では読まれないので
~/.bash_profileからsourceするのが普通。 - 非インタラクティブでもSSH越しの
rsyncとかscpとかで読まれて失敗の原因となる。 環境変数やメッセージをechoしたくなるかもしれないけど、 標準出力や標準エラーへの書き出しは厳禁。 始めに$-とか$PS1を調べて終了するようにしておくと安心。 $BASH_ENV- スクリプト実行直前にこの環境変数の指すファイルを読み込む。
- POSIXモードの
shとして呼ばれた場合は$ENVを読みに行く。 - スクリプトの中で明示的に
sourceするほうが明快で安全なので使わない。
起動時間短縮
まずはプロファイリングしてボトルネックを知る:
# head of .zshenv
zmodload zsh/zprof
# tail of .zshrc
zprof
compinit とかが遅かったり複数回呼ばれていたりするので順番やオプションを変えてみる。
Glob
Qualifiers
ファイルの種類を限定したり順番を変えたりできる。
setopt EXTENDED_GLOB で有効になる。
*(/): directories*(.): plain files*(@): symbolic links*(*): executable plain files*(On),*(^on): descending order by name.
*(Om),*(^om): ascending order by modification time, oldest first.
例えばfileとfile.backupを比較したいときにただdiff file*とするとbackupのほうが後に来てしまうのを解決。 名前順と時間順でデフォルトの方向が逆なのはいずいけど仕方ない。