Zsh

提供: ArchWiki
2022年10月22日 (土) 14:36時点におけるAshMyzk (トーク | 投稿記録)による版 (→‎ヘルプコマンド: 同期)
ナビゲーションに移動 検索に移動

Zsh は対話式シェルとしてもスクリプト言語のインタプリタとしても使えるパワフルなシェルです。POSIX sh と互換性がありながら (デフォルトではありません、emulate sh を実行した時だけです)、タブ補完の改善や グロビングなどの利点があります。

Zsh FAQ には他にも Zsh をあなたのシェルとして使うべき理由が列挙されています。

目次

インストール

インストールをする前に現在使っているシェルが何なのか知っておくとよいでしょう:

$ echo $SHELL

zsh パッケージをインストールしてください。追加の補完定義を使いたい場合は、zsh-completions パッケージもインストールします。

初期設定

ターミナルで次のコマンドを実行して Zsh が正しくインストールされたか確認してください:

$ zsh

基本的な設定を説明する zsh-newuser-install が表示されるはずです。これをスキップしたい場合、q を押して下さい。表示されない場合は、次のコマンドで手動で呼び出すことができます:

$ autoload -Uz zsh-newuser-install
$ zsh-newuser-install -f
ノート: 仮想端末のサイズが少なくとも 72×15 であることを確認してください。そうでないと zsh-newuser-install は実行されません。

Zsh をデフォルトのシェルにする

シェルを /usr/bin/zsh に変更してください。コマンドラインシェル#デフォルトシェルを変更する を見てください。

ヒント: bash を置き換える場合、~/.bashrc から ~/.zshrc に (例: プロンプトとエイリアス) また ~/.bash_profile から ~/.zprofile に (例: X Window System を起動するコード) にコードを移動するとよいでしょう。

スタートアップ/シャットダウン ファイル

ヒント: インタラクティブシェルとログインシェルの説明、およびスタートアップファイルに何を入れるかについては、A User's Guide to the Z-Shell を参照してください。
ノート:
  • $ZDOTDIR が設定されていない場合は、代わりに $HOME が使用されます。
  • RCS オプションが以下のファイルのどれかで unset された場合、そのファイル以降、設定ファイルは読み込まれません。
  • GLOBAL_RCS オプションが以下のファイルのどれかで unset された場合、そのファイル以降、グローバルな設定ファイル (/etc/zsh/*) は読み込まれません。

デフォルトで、Zsh は起動時に以下のファイルを以下の順番で実行します (存在しているもののみ実行されます)。

  • /etc/zsh/zshenv すべてのユーザに対して環境変数を設定するために使用されます。このファイルには、出力を行うコマンドや、シェルが TTY に接続されていることを期待するコマンドを含めるべきではありません。このファイルが存在する場合、このファイルは 常に 読み込まれます。この挙動を上書きすることはできません。
  • $ZDOTDIR/.zshenv ユーザの環境変数を設定するために使用されます。このファイルには、出力を行うコマンドや、シェルが TTY に接続されていることを期待するコマンドを含めるべきではありません。このファイルが存在する場合、このファイルは 常に 読み込まれます。
  • /etc/zsh/zprofile すべてのユーザに対して起動時にコマンドを実行するために使用されます。ログインシェルとして起動した場合に、このファイルは読み込まれます。Arch Linux においては、このファイルには、/etc/profile を source する 1行 がデフォルトで含まれていることを留意しておいてください。その行を削除したい場合は以下の警告を先に読んでください!
    • /etc/profile POSIX sh 互換のシェルはすべて、このファイルをログイン時に source する必要があります。このファイルは $PATH や他の環境変数を設定し、ログイン時にはアプリケーション固有 (/etc/profile.d/*.sh) の設定を行います。
  • $ZDOTDIR/.zprofile 起動時にユーザのコマンドを実行するために使用されます。ログインシェルとして起動した場合に、このファイルは読み込まれます。通常、グラフィカルセッションを自動起動し、セッションの環境変数を設定するために使用されます。
  • /etc/zsh/zshrc すべてのユーザに対して、インタラクティブシェルを設定したりコマンドを実行したりするために使用されます。インタラクティブシェルとして起動した場合に、このファイルは読み込まれます。
  • $ZDOTDIR/.zshrc ユーザのインタラクティブシェルを設定したり、コマンドを実行したりするために使用されます。インタラクティブシェルとして起動した場合に、このファイルは読み込まれます。
  • /etc/zsh/zlogin すべてのユーザに対して初期化処理の最後にコマンドを実行するために使用されます。ログインシェルとして起動した場合に、このファイルは読み込まれます。
  • $ZDOTDIR/.zlogin 初期化処理の最後にユーザのコマンドを実行するために使用されます。ログインシェルとして起動した場合に、このファイルは読み込まれます。通常、コマンドラインユーティリティを自動起動するために使用されます。グラフィカルセッションを自動起動するために使用するべきではありません (この時点では、インタラクティブシェルにおいてのみ意味を持つ設定がセッションに含まれているかもしれないからです)。
  • $ZDOTDIR/.zlogout ログインシェル終了 する時にコマンドを実行するために使用されます。
  • /etc/zsh/zlogout ログインシェル終了 する時にすべてのユーザに対してコマンドを実行するために使用されます。

the graphic representation を参照してください。

ノート: $HOME/.profile は Zsh のスタートアップファイルの一部ではありません。さらに、Zsh によって source されません (Zsh が shksh として実行され、ログインシェルとして起動しない限り)。sh や ksh との互換性モードに関する詳細は zsh(1) § COMPATIBILITY を見てください。
警告: /etc/zsh/zprofile 内にデフォルトで存在する 一行 を削除しないでください。さもないと、/etc/profile.d/ 内へスクリプトを提供するパッケージの整合性が破壊されてしまいます。

Zsh の設定

Zsh は何も設定しなくても使うことができますが、ほとんどのユーザが使いたいと思うようには設定されていないことはほぼ確実です。ただし、Zsh で利用できるカスタマイズの量は膨大で、Zsh を設定するのは大変で時間を浪費する経験となるでしょう。自動的に設定するには #サードパーティ拡張 を見てください。

シンプルな .zshrc

以下は設定ファイルのサンプルです。デフォルトのオプションの適切なセットと共に、Zsh でカスタマイズ可能な方法の例を提供します。この設定を使うには、.zshrc という名前のファイルに保存してください。

ヒント: ログアウトせずに変更を適用するには source ~/.zshrc を実行してください。

これはシンプルな .zshrc です:

~/.zshrc
autoload -Uz compinit promptinit
compinit
promptinit

# デフォルトのプロンプトを walters テーマに設定する
prompt walters

プロンプトテーマシステムに関する詳細は #プロンプトテーマ を見てください。

$PATH の設定

Zsh は PATH 変数を path 配列に結びつけます。これにより、path 配列を変更するだけで PATH 変数を操作することができます。詳細は A User's Guide to the Z-Shell を見てください。

~/.local/bin/PATH に追加するには:

~/.zshenv
typeset -U path PATH
path=(~/.local/bin $path)
export PATH

コマンド補完

Zsh の一番魅力的な機能はおそらく先進的な自動補完機能でしょう。少なくとも .zshrc で自動補完を有効化してください。自動補完を有効にするには、以下を ~/.zshrc に追加してください:

~/.zshrc
autoload -Uz compinit
compinit

上記の設定には ssh/scp/sftp ホスト名の保管が含まれていますが、この機能を動作させるためにはユーザは ssh のホスト名ハッシュ化 (つまり、ssh クライアントの設定の HashKnownHosts オプション) を有効化してはなりません。

矢印キーを使うインターフェイスで自動補完を行うには、以下を追加してください:

~/.zshrc
zstyle ':completion:*' menu select

メニューをアクティブにするには、Tab を2回押してください。

特権が与えられたコマンドで特権環境の自動補完を有効化するには (例えば、sudo で始まるコマンドを補完する場合、補完スクリプトは sudo の補完もしようと試みます)、以下を追加してください:

~/.zshrc
zstyle ':completion::complete:*' gain-privileges 1
警告: これにより、Zsh の補完スクリプトが sudo 特権でコマンドを実行できてしまいます。信頼できない補完スクリプトを使用する場合はこれを有効化すべきではありません。
ノート: この特殊な種類の文脈依存の補完は、少数のコマンドでしか利用できません。

キーバインド

Zsh は readline を使用しません。代わりに、よりパワフルな独自の Zsh Line Editor (ZLE) を使用します。ZLE は /etc/inputrc~/.inputrc のどちらも読み込みません。ZLE 設定のイントロダクションは A closer look at the zsh line editor and creating custom widgets を読んでください。

ZLE には Emacs モードと vi モードがあります。VISUALEDITOR のどちらか一方の環境変数vi という文字列が含まれている場合、vi モードが使用されます。それ以外の場合、Emacs モードをデフォルトで使用します。bindkey -e (Emacs モード) や bindkey -v (vi モード) でモードを明示的に設定することもできます。

キーバインドは、キープレスに対応するエスケープシーケンスを ZLE ウィジェットにマッピングすることにより割り当てます。利用可能なウィジェットは zshzle(1) § STANDARD WIDGETSzshcontrib(1) § ZLE FUNCTIONS にリストアップされています (アクションとデフォルトのキーバインドの説明付き)。

Zsh でキーバインドを設定する方法として推奨されるのは、terminfo(5) の文字列ケーパビリティを使用することです。例えば [1][2]:

~/.zshrc
# zkbd と互換性のあるハッシュテーブルを作成し、
# 他のキーをこのハッシュテーブルに追加する (man 5 terminfo を参照)
typeset -g -A key

key[Home]="${terminfo[khome]}"
key[End]="${terminfo[kend]}"
key[Insert]="${terminfo[kich1]}"
key[Backspace]="${terminfo[kbs]}"
key[Delete]="${terminfo[kdch1]}"
key[Up]="${terminfo[kcuu1]}"
key[Down]="${terminfo[kcud1]}"
key[Left]="${terminfo[kcub1]}"
key[Right]="${terminfo[kcuf1]}"
key[PageUp]="${terminfo[kpp]}"
key[PageDown]="${terminfo[knp]}"
key[Shift-Tab]="${terminfo[kcbt]}"

# 適宜キーを設定する
[[ -n "${key[Home]}"      ]] && bindkey -- "${key[Home]}"       beginning-of-line
[[ -n "${key[End]}"       ]] && bindkey -- "${key[End]}"        end-of-line
[[ -n "${key[Insert]}"    ]] && bindkey -- "${key[Insert]}"     overwrite-mode
[[ -n "${key[Backspace]}" ]] && bindkey -- "${key[Backspace]}"  backward-delete-char
[[ -n "${key[Delete]}"    ]] && bindkey -- "${key[Delete]}"     delete-char
[[ -n "${key[Up]}"        ]] && bindkey -- "${key[Up]}"         up-line-or-history
[[ -n "${key[Down]}"      ]] && bindkey -- "${key[Down]}"       down-line-or-history
[[ -n "${key[Left]}"      ]] && bindkey -- "${key[Left]}"       backward-char
[[ -n "${key[Right]}"     ]] && bindkey -- "${key[Right]}"      forward-char
[[ -n "${key[PageUp]}"    ]] && bindkey -- "${key[PageUp]}"     beginning-of-buffer-or-history
[[ -n "${key[PageDown]}"  ]] && bindkey -- "${key[PageDown]}"   end-of-buffer-or-history
[[ -n "${key[Shift-Tab]}" ]] && bindkey -- "${key[Shift-Tab]}"  reverse-menu-complete

# 最後に、zle がアクティブのときにターミナルがアプリケーションモードになるようにする。
# そのときにだけ、$terminfo の値が有効になる。
if (( ${+terminfo[smkx]} && ${+terminfo[rmkx]} )); then
	autoload -Uz add-zle-hook-widget
	function zle_application_mode_start { echoti smkx }
	function zle_application_mode_stop { echoti rmkx }
	add-zle-hook-widget -Uz zle-line-init zle_application_mode_start
	add-zle-hook-widget -Uz zle-line-finish zle_application_mode_stop
fi

履歴検索

以下の手順を使うには、key 配列を設定し、ZLE がアプリケーションモードとなるようにする必要があります。#キーバインド を見てください。

履歴検索を有効化するには、以下を .zshrc ファイルに追加してください:

~/.zshrc
autoload -Uz up-line-or-beginning-search down-line-or-beginning-search
zle -N up-line-or-beginning-search
zle -N down-line-or-beginning-search

[[ -n "${key[Up]}"   ]] && bindkey -- "${key[Up]}"   up-line-or-beginning-search
[[ -n "${key[Down]}" ]] && bindkey -- "${key[Down]}" down-line-or-beginning-search

これにより、UpDown を押したときに、現在の行のカーソル位置までにマッチする過去のコマンドだけが表示されます。

修飾キー Shift、Alt、Ctrl、Meta

xterm 互換端末は user_caps(5) からの拡張キー定義を使うことができます。キー定義は、ShiftAltCtrlMeta と、UpDownLeftRightPageUpPageDownHomeEndDel のどれかを組み合わせたものです。修飾キーとキーの組み合わせに推奨される名前の一覧については、zkbd のソース を参照してください。

たとえば、 Ctrl+Left で前の単語の先頭に移動し、Ctrl+Right で次の単語の先頭に移動させるには:

~/.zshrc
key[Control-Left]="${terminfo[kLFT5]}"
key[Control-Right]="${terminfo[kRIT5]}"

[[ -n "${key[Control-Left]}"  ]] && bindkey -- "${key[Control-Left]}"  backward-word
[[ -n "${key[Control-Right]}" ]] && bindkey -- "${key[Control-Right]}" forward-word

プロンプト

Zsh は2つの選択肢を提供します: プロンプトテーマを使用するか、テーマに不満がある (または、テーマの使いやすさを自分で拡張したい) ユーザはカスタムのプロンプトを構築できます。

プロンプトテーマ

プロンプトテーマは、Zsh で色付きのプロンプトを設定するための手っ取り早く簡単な方法です。プロンプトテーマや、プロンプトテーマを自分で記述する方法については zshcontrib(1) § PROMPT THEMES を参照してください。

テーマを使用するには、プロンプトテーマシステムが自動でロードされるように .zshrc で設定されていることを確認してください。自動ロードを行うには、以下の行を追加します:

~/.zshrc
autoload -Uz promptinit
promptinit

以下のコマンドで、利用可能なプロンプトテーマをリストアップできます:

$ prompt -l

例えば、walters テーマを使うには:

$ prompt walters

利用可能なテーマをすべてプレビューするには:

$ prompt -p
プロンプトテーマを手動でインストールする

外部の設定管理ツールを使わずに、テーマを手動でインストールすることもできます。ローカルにインストールする場合、まずフォルダを作成し、そのフォルダのパスを fpath 配列に追加してください。例えば:

$ mkdir ~/.zprompts
$ fpath=("$HOME/.zprompts" "$fpath[@]")

次に、このフォルダ内にテーマファイルのシンボリックリンクを作成します:

$ ln -s mytheme.zsh ~/.zprompts/prompt_mytheme_setup

代わりにテーマをグローバルにインストールする場合は、次のようにします:

# ln -s mytheme.zsh /usr/share/zsh/functions/Prompts/prompt_mytheme_setup

これで、次のコマンドを使ってアクティブ化できるはずです:

$ prompt mytheme

すべてが機能する場合は、.zshrc を適宜編集することができます。

テーマごとにファイルを分けずにプロンプトテーマを追加する

プロンプトテーマは、テーマのファイルを使って追加するだけでなく、ある1つのファイル (例えば .zshrc) 内からテーマを追加することもできます。例えば:

~/.zshrc
# promptinit をロードする
autoload -Uz promptinit && promptinit

# テーマを定義する
prompt_mytheme_setup() {
  PS1="%~%# "
}

# promptsys にそのテーマを追加する
prompt_themes+=( mytheme )

# テーマをロードする
prompt mytheme

プロンプトのカスタマイズ

すべてのシェルで一般的な主要な左側のプロンプト PS1 (PROMPTprompt) に加えて、Zsh では右側のプロンプト RPS1 (RPROMPT) もサポートしています。これら2つの変数は、好きな値にカスタムできます。

他の特殊な目的のためのプロンプト (PS2 (PROMPT2)、PS3 (PROMPT3)、PS4 (PROMPT4)、RPS1 (RPROMPT)、RPS2 (RPROMPT2)、SPROMPT など) は zshparam(1) § PARAMETERS USED BY THE SHELL で説明されています。

すべてのプロンプトは、プロンプトエスケープでカスタマイズできます (例えば、%n はユーザ名になります)。利用可能なプロンプトエスケープは zshmisc(1) § EXPANSION OF PROMPT SEQUENCES でリストアップされています。

Zsh は、Bash とは異なる方法で色を設定します。ANSI エスケープシーケンスや、terminfo(5) のターミナルケーパビリティを多用する必要はありません。Zsh は、前景色、背景色、他の視覚エフェクトを設定するための便利なプロンプトエスケープを提供します。エスケープのリストや説明は zshmisc(1) § Visual effects を見てください。

を指定する方法は3つあります: 10進数の整数、8つの広くサポートされている色の名前、# のあとに16進数の RGB トリプレット。詳細は zshzle(1) § CHARACTER HIGHLIGHTING 内の fg=colour の説明を見てください。

ほとんどのターミナルは以下の色を名前でサポートしています:

名前 番号
black 0
red 1
green 2
yellow 3
blue 4
magenta 5
cyan 6
white 7

xterm 256 color と互換性のあるターミナルエミュレータの色番号 0 から 255 は、xterm-256color チャートで見られます。

TERM 環境変数が正しく設定されていれば、ターミナルのサポートする色の最大数は、terminfo(5) データベースから echoti colors を使って確認することができます。24-bit カラーの場合は、print $COLORTERM を使って COLORTERM 環境変数も確認してください。24bittruecolor を返した場合、たとえ terminfo がより少ない数値を表示したとしても、あなたのターミナルは 16777216 (224) 色をサポートしています。

ノート:
  • 0 から 15 の色は、ターミナルエミュレータやカラースキームごとに異なる場合があります。
  • 多くのターミナルエミュレータは、太文字を明るい色で表示します。
ヒント:
  • プロンプトのエスケープは print -P "prompt escapes" コマンドでテストできます。例えば、
    $ print -P '%B%F{red}co%F{green}lo%F{blue}rs%f%b'
  • 24 ビットカラーを使用する場合、24 ビットカラーをサポートしていないターミナルでは zsh/nearcolor モジュールをロードする必要があるかもしれません。例えば:
    [[ "$COLORTERM" == (24bit|truecolor) || "${terminfo[colors]}" -eq '16777216' ]] || zmodload zsh/nearcolor
    zsh/nearcolor モジュールに関する詳細は zshmodules(1) § THE ZSH/NEARCOLOR MODULE を見てください。

これは、シンプルな色無しのプロンプトの例です:

PROMPT='%n@%m %~ %# '

以下のように出力されます:

username@host ~ %

これは、色付きの左右両方のプロンプトの例です:

PROMPT='%F{green}%n%f@%F{magenta}%m%f %F{blue}%B%~%b%f %# '
RPROMPT='[%F{yellow}%?%f]'

以下のように出力されます:

username@host ~ % [0]

16-255 の範囲の色は、欲しい色に割り当てた 0 から 255 までの数値を使うことで使用できます。また、24 ビットトゥルーカラーは16進数のカラーコードを使うことで使用できます:

PROMPT='%F{2}%n%f@%F{5}%m%f %F{4}%B%~%b%f %# '
RPROMPT='[%F{3}%?%f]'
PROMPT='%F{#c0c0c0}%n%f@%F{#008000}%m%f %F{#800080}%B%~%b%f %# '
RPROMPT='[%F{#0000ff}%?%f]'

サンプルの .zshrc ファイル

さらに見たい場合は ドットファイル#ユーザーリポジトリ を見てください。

ヒントとテクニック

ログイン時に X を自動起動

xinit#ログイン時に X を自動起動を参照してください。

プログラムが異常終了した後、端末の設定を復元する

多くのプログラムはターミナルの状態を変更し、異常終了したときにターミナルの設定を復元しないことがあります (例えば、クラッシュしたときや、SIGINT を受け取ったとき)。

通常、これは reset(1) を実行することで解決できます:

$ reset

以下のセクションでは、手動でターミナルをリセットする手間を省く方法について説明します。

ttyctl コマンド

ttyctl コマンドを使ってターミナルを "freeze/unfreeze" することができます。起動時にインタラクティブシェルを freeze させるには、以下を使用してください:

~/.zshrc
ttyctl -f

エスケープシーケンスで端末をリセットする

A代替の線画文字セットは、ttyctl が防ぐことができない方法でターミナルを台無しにしてしまうことがあります。

シンプルな解決法は、ターミナルをリセットするエスケープシーケンスを precmd フック関数から出力することです。そうすれば、プロンプトが描画される前に毎回、そのエスケープシーケンスが出力されます。例えば、エスケープシーケンス \e[0m\e(B\e)0\017\e[?5l\e7\e[0;0r\e8 を使うと:

~/.zshrc
autoload -Uz add-zsh-hook

function reset_broken_terminal () {
	printf '%b' '\e[0m\e(B\e)0\017\e[?5l\e7\e[0;0r\e8'
}

add-zsh-hook -Uz precmd reset_broken_terminal

うまく行くか試すには、以下を実行してください:

$ print '\e(0\e)B'

最近のディレクトリを記憶させる

Dirstack

Zsh は、最後に訪れたフォルダのうち DIRSTACKSIZE 個を記憶するように設定できます。この機能を活用すれば、それらのフォルダへ非常に素早く cd することができます。設定ファイルにいくつかの行を追加する必要があります:

~/.zshrc
autoload -Uz add-zsh-hook

DIRSTACKFILE="${XDG_CACHE_HOME:-$HOME/.cache}/zsh/dirs"
if [[ -f "$DIRSTACKFILE" ]] && (( ${#dirstack} == 0 )); then
	dirstack=("${(@f)"$(< "$DIRSTACKFILE")"}")
	[[ -d "${dirstack[1]}" ]] && cd -- "${dirstack[1]}"
fi
chpwd_dirstack() {
	print -l -- "$PWD" "${(u)dirstack[@]}" > "$DIRSTACKFILE"
}
add-zsh-hook -Uz chpwd chpwd_dirstack

DIRSTACKSIZE='20'

setopt AUTO_PUSHD PUSHD_SILENT PUSHD_TO_HOME

## 重複するエントリを削除する
setopt PUSHD_IGNORE_DUPS

## +/- 演算子をもとに戻す。
setopt PUSHD_MINUS

これで、以下のコマンドを使えば dirstack を出力できます。 Now use

$ dirs -v

訪れたフォルダに戻るには cd -<NUM> を使ってください。ダッシュ記号の後でオートコンプリートを使ってください。オートコンプリートメニューを使う場合に便利です。

ノート: 2つ以上の zsh セッションを開いていて cd をしようとした場合、両方のセッションが同じファイルに書き込むことで競合が発生するため、これは動作しません。

cdr

cdr により、自動的に管理されるリストを使って現在の作業ディレクトリから以前の作業ディレクトリに移動することができます。cdr は、現在のセッションでセッション間および (デフォルトで) ターミナルエミュレータ間で管理されるファイルにすべてのエントリを保存します。

セットアップの手順は zshcontrib(1) § REMEMBERING RECENT DIRECTORIES を見てください。

zoxide

zoxide は、よりスマートな cd コマンドで、数個のキーストロークで好きな場所に移動できます。zoxide は、頻繁に使用されるディレクトリを記憶し、スコアリングメカニズムを使って、あなたが行きたい場所を推測します。

ヘルプコマンド

Bash とは違い、Zsh は組み込みの help コマンドを有効化しておらず、代わりに run-help を提供しています。デフォルトでは、run-helpman のエイリアスとなっています。コマンドの前に run-help と付けることで実行できますし、または今タイプしたコマンドに対してキーボードショートカット Alt+hEsc h を入力することでも実行できます。

デフォルトでは man のエイリアスとなっているので、外部コマンドに対してしか動作しません。シェルの組み込みコマンドやシェルの他の機能でも動作するようにするには、run-help 関数を使う必要があります。run-help や補助関数については zshcontrib(1) を見てください。

まず、run-help 関数をロードし、その次に既存の run-help エイリアスを削除してください。helprun-help へのエイリアスにすることもできます。例えば、以下を zshrc に追加してください:

autoload -Uz run-help
(( ${+aliases[run-help]} )) && unalias run-help
alias help=run-help

補助関数は別で有効化する必要があります:

autoload -Uz run-help-git run-help-ip run-help-openssl run-help-p4 run-help-sudo run-help-svk run-help-svn

例えば、run-help git commit コマンドは、git(1) ではなく git-commit(1)man ページを開きます。

継続的に rehash する

通常、compinit は $PATH 内の新しい実行ファイルを自動的には見つけません。例えば、新しいパッケージをインストールした後、/usr/bin/ 内に追加された新しいファイルは即座に、または自動的には補完に含まれないでしょう。なので、そのような新しい実行ファイルを補完に含めるために、以下を実行します:

$ rehash

この 'rehash' は、自動的に実行するよう設定できます。[3] 以下を zshrc に追加するだけです:

~/.zshrc
zstyle ':completion:*' rehash true

必要なときにだけ rehash する

しかし、pacmanフックを使って、自動的に rehash を要求するように設定できます。こうすれば、先のセクションのように継続的に rehash してパフォーマンスが劣化してしまうようなことは起こりません。これを有効化するには、/etc/pacman.d/hooks ディレクトリと /var/cache/zsh ディレクトリを作成し、フックファイルを作成してください:

/etc/pacman.d/hooks/zsh.hook
[Trigger]
Operation = Install
Operation = Upgrade
Operation = Remove
Type = Path
Target = usr/bin/*
[Action]
Depends = zsh
When = PostTransaction
Exec = /usr/bin/install -Dm644 /dev/null /var/cache/zsh/pacman

これは、/var/cache/zsh/pacman ファイルの変更日時を、最後にパッケージをインストール/アップグレード/アンインストールした時間に合わせます。次に、zsh のコマンドキャッシュが古くなったときにコマンドキャッシュを rehash するように設定します。以下を ~/.zshrc に追加してください:

~/.zshrc
zshcache_time="$(date +%s%N)"

autoload -Uz add-zsh-hook

rehash_precmd() {
  if [[ -a /var/cache/zsh/pacman ]]; then
    local paccache_time="$(date -r /var/cache/zsh/pacman +%s%N)"
    if (( zshcache_time < paccache_time )); then
      rehash
      zshcache_time="$paccache_time"
    fi
  fi
}

add-zsh-hook -Uz precmd rehash_precmd

/var/cache/zsh/pacman が更新されるまえに precmd フックがトリガーされた場合、新しいプロンプトが始まるまで補完が効かないかもしれません。そういうときは、空のコマンドを実行すれば良いはずです (例えば、enter を押す)。

SIGUSR1 を使って必要なときにだけ rehash する

フックファイルは以下のようになります。

/etc/pacman.d/hooks/zsh-rehash.hook
[Trigger]
Operation = Install
Operation = Upgrade
Operation = Remove
Type = Path
Target = usr/bin/*

[Action]
Depends = zsh
Depends = procps-ng
When = PostTransaction
Exec = /usr/bin/pkill zsh --signal=USR1
警告: このフックは、実行中の zsh インスタンスすべてに SIGUSR1 を送信します。注意すべきなのは、SIGUSR1 のデフォルトの挙動は「終了」だということです。なので、このフックを先に設定してしまうと、すべてのユーザの実行中の zsh インスタンス (ログインシェルも含む) のうち以下のトラップを source していないものが、終了してしまいます。
~/.zshrc
TRAPUSR1() { rehash }

この 関数トラップ は、リストトラップ trap 'rehash' USR1 に置き換えることもできます。トラップの種類の違いについては zshmisc(1) § Trap Functions を見てください。

この方法は、すべての zsh インスタンスを即座に rehash します。なので、precmd をトリガーするためにエンターキーを押す必要がありません。

ncurses アプリケーションにキーをバインド

ncurses アプリケーションをキーストロークにバインドしますが、対話を受け入れません。これを動作させるには BUFFER 変数を使用します。次の例では、Alt+\ を使用して ncmpcpp を開くことができます。

~/.zshrc
ncmpcppShow() {
  BUFFER="ncmpcpp"
  zle accept-line
}
zle -N ncmpcppShow
bindkey '^[\' ncmpcppShow

アプリケーションを呼び出す前に、行に入力した内容をすべて保持する別の方法

~/.zshrc
ncmpcppShow() {
  ncmpcpp <$TTY
  zle redisplay
}
zle -N ncmpcppShow
bindkey '^[\' ncmpcppShow

ファイルマネージャー風のキーバインド

グラフィックファイルマネージャで使われているようなキーバインドが便利かもしれません。1つ目はディレクトリ履歴 (Alt+Left) に戻り、2つ目はユーザを親ディレクトリ (Alt+Up) に移動させます。また、ディレクトリの内容も表示されます。

~/.zshrc
cdUndoKey() {
  popd
  zle       reset-prompt
  print
  ls
  zle       reset-prompt
}

cdParentKey() {
  pushd ..
  zle      reset-prompt
  print
  ls
  zle       reset-prompt
}

zle -N                 cdParentKey
zle -N                 cdUndoKey
bindkey '^[[1;3A'      cdParentKey
bindkey '^[[1;3D'      cdUndoKey

xterm タイトル

端末エミュレータがサポートしている場合は、タイトルを Zsh から設定できます。これにより、タイトルを動的に変更して、シェルの状態に関する関連情報 (ユーザ名や現在のディレクトリ、現在実行中のコマンドなど) を表示できます。

xterm のタイトルは xterm escape sequence \e]2;\a 例:

$ print -n '\e]2;My xterm title\a'

タイトルを設定します

My xterm title

動的タイトルを簡単に設定するには、precmd および preexec フック関数でタイトルを設定します。使用可能なフック関数のリストとその説明については、zshmisc(1) § Hook Functions を参照してください。

さらに print-P を使うと、Zsh のプロンプトエスケープを利用することができます。

ヒント:
  • タイトルプリントは、連続している限り、複数のコマンドに分割できます。
  • GNU Screen で xterm のタイトルをハードステータス (%h) に送る。 string escapes (例:色) を使用したい場合は、\e_\e\\ エスケープシーケンスでハードステータスを設定する必要があります。そうでなければ、文字列エスケープが \e] 2;\a と入力すると、Screen の文字列エスケープを解釈できないため、ターミナルエミュレータのタイトルが文字化けします。
ノート:
  • 変数がプロンプトエスケープとして解析されないようにするため、変数を出力するときに -P-P オプションを使用しないでください。
  • 変数を出力する際に q パラメータ展開フラグ を使用して、エスケープシーケンスとして解析されないようにします。
~/.zshrc
autoload -Uz add-zsh-hook

function xterm_title_precmd () {
	print -Pn -- '\e]2;%n@%m %~\a'
	[[ "$TERM" == 'screen'* ]] && print -Pn -- '\e_\005{g}%n\005{-}@\005{m}%m\005{-} \005{B}%~\005{-}\e\\'
}

function xterm_title_preexec () {
	print -Pn -- '\e]2;%n@%m %~ %# ' && print -n -- "${(q)1}\a"
	[[ "$TERM" == 'screen'* ]] && { print -Pn -- '\e_\005{g}%n\005{-}@\005{m}%m\005{-} \005{B}%~\005{-} %# ' && print -n -- "${(q)1}\e\\"; }
}

if [[ "$TERM" == (Eterm*|alacritty*|aterm*|gnome*|konsole*|kterm*|putty*|rxvt*|screen*|tmux*|xterm*) ]]; then
	add-zsh-hook -Uz precmd xterm_title_precmd
	add-zsh-hook -Uz preexec xterm_title_preexec
fi

ターミナルエミュレータのタブのタイトル

一部のターミナルエミュレータおよびマルチプレクサは、タブのタイトルの設定をサポートしています。エスケープシーケンスは端末によって異なります。

ターミナル エスケープシーケンス 説明
GNU Screen \ek\e\\ Screen' ウィンドウタイトル (%t).
Konsole \e]30;\a Konsole' タブタイトル.

シェル環境の検出

シェル環境を検出するテストについては、a repository about shell environment detection を参照してください。これには、ログイン/対話シェル、 Xorg セッション、TTY、および SSH セッションが含まれます。

/dev/tcp equivalent: ztcp

zsh/net/tcp モジュールを使用します。

$ zmodload zsh/net/tcp

TCP 接続を確立できるようになりました。

$ ztcp example.com 80

コマンドラインの一部でシェルを終了するショートカット

デフォルトでは、コマンドラインがいっぱいになっても Ctrl+d はシェルを閉じません、次のように修正します。

.zshrc
exit_zsh() { exit }
zle -N exit_zsh
bindkey '^D' exit_zsh

pacman -F "command not found" ハンドラー

pacman には、ファイルを含むパッケージを検索する機能が含まれています。次の command-not-found ハンドラは、不明なコマンドが実行されたときに、pacman を直接使用して一致するパッケージを検索します。

~/.zshrc
...
function command_not_found_handler {
    local purple='\e[1;35m' bright='\e[0;1m' green='\e[1;32m' reset='\e[0m'
    printf 'zsh: command not found: %s\n' "$1"
    local entries=(
        ${(f)"$(/usr/bin/pacman -F --machinereadable -- "/usr/bin/$1")"}
    )
    if (( ${#entries[@]} ))
    then
        printf "${bright}$1${reset} may be found in the following packages:\n"
        local pkg
        for entry in "${entries[@]}"
        do
            # (repo package version file)
            local fields=(
                ${(0)entry}
            )
            if [[ "$pkg" != "${fields[2]}" ]]
            then
                printf "${purple}%s/${bright}%s ${green}%s${reset}\n" "${fields[1]}" "${fields[2]}" "${fields[3]}"
            fi
            printf '    /%s\n' "${fields[4]}"
            pkg="${fields[2]}"
        done
    fi
}
...
ノート: pacman のファイル・データベースは通常の同期データベースとは別のもので、pacman-Fy を使用してフェッチする必要があります。詳細については、 pacman#特定のファイルが含まれているパッケージを検索 を参照してください。

pkgfile ファイル を使用する別の方法については、zsh#"command not found" フック を参照してください。

キーバインディングによるバックバッファのクリア

デフォルトでは、ほとんどのターミナル・エミュレータで、画面クリアのキーバインドがバックバッファ(上にスクロールしないと見えない部分)をクリアしません。この問題を解決する方法として、次のようなものが考えられます。

~/.zshrc
...
function clear-screen-and-scrollback() {
    echoti civis >"$TTY"
    printf '%b' '\e[H\e[2J' >"$TTY"
    zle .reset-prompt
    zle -R
    printf '%b' '\e[3J' >"$TTY"
    echoti cnorm >"$TTY"
}

zle -N clear-screen-and-scrollback
bindkey '^L' clear-screen-and-scrollback
...

サードパーティ拡張

設定フレームワーク

ノート: フレームワークは、抽象化と複雑化のレベルを導入します。それらは未定義の挙動をもたらす可能性があり、シェルが壊れた場合、最初の デバッグステップは、プレーンなシェルに戻ることです。
  • oh-my-zsh — Zsh の設定を管理するためのコミュニティ運営の人気なフレームワークです。たくさんの便利な関数、ヘルパー、プラグイン、テーマをバンドルしています。
https://github.com/ohmyzsh/ohmyzsh || oh-my-zsh-gitAUR
  • Prezto — Zsh 用の設定フレームワークです。モジュールが同梱されており、適切なデフォルト、エイリアス、関数、オートコンプリート、プロンプトテーマでコマンドラインインターフェイス環境を充実させることができます。
https://github.com/sorin-ionescu/prezto || prezto-gitAUR
  • ZI — Zsh Unix シェルにおけるスイスアーミーナイフです。
https://github.com/z-shell/zi || パッケージが存在しないか AUR で検索
  • ZIM — 驚異的なスピードとモジュール式拡張機能の付いた設定フレームワークです。Zim はとても簡単にカスタマイズでき、スピードと機能性を犠牲にせず、モジュールと機能の豊富なセットが付属しています。
https://github.com/zimfw/zimfw || zsh-zim-gitAUR

プラグインマネージャー

  • Antidote — レガシーな Antibody プラグインマネージャの完全な Zsh 実装です。
https://github.com/mattmc3/antidote || zsh-antidoteAUR
  • zinit (以前の名称は "zplugin") — 柔軟な Zsh プラグインマネージャ。クリーンな fpath、レポート、補完管理、ターボモードが付いています。復活しました
https://github.com/zdharma-continuum/zinit || zinit-gitAUR
  • Antigen — Zsh 用のプラグインマネージャ。oh-my-zsh と vundle にインスパイアされました。放棄されています
https://github.com/zsh-users/antigen || antigen-gitAUR
https://github.com/tarjoilija/zgen || zgen-gitAUR
https://github.com/zplug/zplug || zplugAUR

Fish のようなシンタックスハイライトとオートサジェスト

Fish には強力なシェルシンタックスハイライトとオートサジェスト機能があります。これらの機能を zsh で使うには、zsh-syntax-highlightingzsh-autosuggestions をインストールし、提供されたスクリプトの一方または両方を zshrc から source してください:

source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
source /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh

pkgfile の "command not found" ハンドラー

pkgfile には、command_not_found_handler 関数を提供する Zsh スクリプトファイルが含まれています。この関数は、認識されないコマンドが入力されたときに、pkgfile のデータベースを自動的に検索します。

この関数を有効化するには、そのスクリプトを source する必要があります。例えば:

~/.zshrc
source /usr/share/doc/pkgfile/command-not-found.zsh
ノート: pkgfile のデータベースは、この機能を使う前に更新が必要な場合があります。詳細は pkgfile#インストール を見てください。

pacman のネイティブな機能を使う代替は、#pacman -F "command not found" ハンドラー を見てください。

参照