Zsh

提供: ArchWiki
2022年10月20日 (木) 17:38時点における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/ 内へスクリプトを提供するパッケージの整合性が破壊されてしまいます。

~/.zshrc の設定

Zsh は何も設定しなくても使うことができますが、あなたが使いたい機能はほとんど設定されていないでしょう。ただし Zsh で利用できるカスタム化の道は険しく、Zsh の設定は困難をきわめ多くの時間を浪費するかもしれません。

シンプルな .zshrc

下にはサンプルの設定ファイルが含まれており、Zsh のカスタマイズの方法の例だけでなくデフォルトオプションのセットも提供しています。この設定を使うには .zshrc という名前でファイルを保存してください。ログインしなおさなくても次を実行することで変更を適用できます:

$ source ~/.zshrc

以下はシンプルな .zshrc です、基点としてはピッタリでしょう:

~/.zshrc
autoload -U compinit promptinit
compinit
promptinit

# This will set the default prompt to the walters theme
prompt walters

$PATH の設定

通常、PATH は ~/.zshenv で設定すべきですが、Arch Linux は ~/.zshenv を読み込んだ後に /etc/profile を読み込みます (全体の流れは設定ファイルを見てください)。

$PATH の上書きを防ぐために、~/.zprofile で設定するようにしてください:

~/.zprofile
typeset -U path
path=(~/bin /other/things/in/path $path[@])

詳しくは Z-Shell のユーザーガイド を参照してください。

コマンド補完

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

~/.zshrc
autoload -U compinit
compinit

この設定は ssh/scp/sftp のホスト名の補完も含んでいますが、この機能を動かすには ~/.ssh/known_hosts で ssh がホスト名をハッシュ化しないようにする必要があります。

警告: ハッシュ化を解除すると "Island-hopping" 攻撃 に無防備になります。そのことを前もって知った上で、次の行をコメントアウトするか値を no に設定してください:
/etc/ssh/ssh_config
#HashKnownHosts yes

これで ~/.ssh/known_hosts をどこか他のところに移動すれば ssh はハッシュ化されてないホスト名を使って新しいファイルを作成します (以前のホストは消失します)。詳細については、hashed-hosts に関する SSH の readme を見て下さい。

矢印キーのインターフェイスを使って自動補完するには、以下を追加して下さい:

~/.zshrc
zstyle ':completion:*' menu select
メニューを有効にするには、タブを二度押して下さい。

エイリアスでコマンドラインの自動補完を切り替えるには、以下を追加して下さい:

~/.zshrc
setopt completealiases

キーバインド

Zsh は readline を使っていません、代わりに自身のパワフルな zle を使っています。zle は /etc/inputrc~/.inputrc を読みません。 zle には emacs モードと vi モードがあります。デフォルトでは、$EDITOR 環境変数から emacs と vi どちらのキーをあなたが使いたいのか考えます。この変数が空の場合、デフォルトは emacs モードです。 bindkey -vbindkey -e でモードを変更することが可能です。

特殊なキーを動作させるには:

~/.zshrc
# create a zkbd compatible hash;
# to add other keys to this hash, see: man 5 terminfo
typeset -A key

key[Home]=${terminfo[khome]}

key[End]=${terminfo[kend]}
key[Insert]=${terminfo[kich1]}
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]}

# setup key accordingly
[[ -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[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

# Finally, make sure the terminal is in application mode, when zle is
# active. Only then are the values from $terminfo valid.
if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then
    function zle-line-init () {
        printf '%s' "${terminfo[smkx]}"
    }
    function zle-line-finish () {
        printf '%s' "${terminfo[rmkx]}"
    }
    zle -N zle-line-init
    zle -N zle-line-finish
fi
ノート: 特定のキーの組み合わせに対して適切なシーケンスを取得するには、 cat を起動するか、パラメーターなしで read を押します。 その後、端末に印刷する必要があります。 Ctrl+c を使用して両方を再び閉じることができます。

履歴検索

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

これにより、up または down キーを押すと、現在の行から現在のカーソル位置までに一致する過去のコマンドのみが表示されます。

Shift, Alt, Ctrl and Meta 修飾キー

xterm 互換端末は user_caps(5) からの拡張キー定義を使うことができます。 ShiftAltCtrl、 および Meta と、 UpDownLeftRightPageUpPageDownHomeEnd、 または Del を組み合わせたものです。修飾キーとキーの組み合わせに推奨される名前の一覧については、 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 は、プロンプトテーマを使用するか、テーマに不満がある (またはその有用性を拡張したい) ユーザーのために、カスタムプロンプトを構築するオプションを提供しています。

プロンプトテーマ

プロンプトテーマは、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 をそれに応じて編集することができます。

ファイルの無いプロンプトテーマを追加する

プロンプトテーマを独自のファイルから追加するだけでなく、次のように別のファイル (.zshrc のように)からテーマを追加することもできます。 例えば:

~/.zshrc
# Load promptinit
autoload -Uz promptinit && promptinit

# Define the theme
prompt_mytheme_setup() {
  PS1="%~%# "
}

# Add the theme to promptsys
prompt_themes+=( mytheme )

# Load the theme
prompt mytheme

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

上述のプロンプトに満足がいかない(もしくはプロンプトを拡張したい)場合、Zsh にはカスタムプロンプトを作る機能が備わっています。全てのシェルに共通な左側だけのプロンプトに加え、Zsh は左右両側を使うプロンプトをサポートしています。PROMPT= と以下の変数を使うことでプロンプトをカスタマイズできます:

Colors

Zsh sets colors differently than Bash; You do not need to use profuse ANSI escape sequences or terminal capabilities from terminfo(5). Zsh provides convenient prompt escapes to set the foreground color, background color and other visual effects; see zshmisc(1) § Visual effects for a list of them and their descriptions.

Colors can be specified using a decimal integer, the name of one of the eight most widely-supported colors or as a # followed by an RGB triplet in hexadecimal format. See the description of fg=colour in zshzle(1) § CHARACTER HIGHLIGHTING for more details.

Most terminals support the following colors by name:

Name Number
black 0
red 1
green 2
yellow 3
blue 4
magenta 5
cyan 6
white 7

Color numbers 0–255 for terminal emulators compatible with xterm 256 colors can be found in the xterm-256color chart.

With a correctly set TERM environment variable, the terminal's supported maximum number of colors can be found from the terminfo(5) database using echoti colors. In the case of 24-bit colors, also check the COLORTERM environment variable with print $COLORTERM. If it returns 24bit or truecolor then your terminal supports 16777216 (224) colors even if terminfo shows a smaller number.

ノート:
  • The colors 0–15 may differ between terminal emulators and their used color schemes.
  • Many terminal emulators display bold with a brighter color.
ヒント:
  • Prompt escapes can be tested with command print -P "prompt escapes", for example:
    $ print -P '%B%F{red}co%F{green}lo%F{blue}rs%f%b'
  • If you use 24-bit colors, you might want to load the zsh/nearcolor module in terminals that do not support them. E.g.:
    [[ "$COLORTERM" == (24bit|truecolor) || "${terminfo[colors]}" -eq '16777216' ]] || zmodload zsh/nearcolor
    See zshmodules(1) § THE ZSH/NEARCOLOR MODULE for details about the zsh/nearcolor module.
プロンプト変数
コマンド 説明 コメント
一般
%n ユーザー名
%m コンピュータのホスト名 (ドットの前の部分まで)
%M コンピュータのホスト名
%l 現在の tty
%? 最後に実行したアプリケーションのリターンコード
%# ユーザー特権によるプロンプト (root なら # その他なら %)
時間
%T システム時刻 (HH:MM)
%* システム時刻 (HH:MM:SS)
%D システム日付 (YY-MM-DD)
ディレクトリ
%d カレントディレクトリ。 数字を前に付けることでパスの一部だけを表示することが可能です。例えば %1d と入力した場合、/usr/bin にいるときは bin と表示されます。負の値も使えます: %-1d は上の例だと / と表示されます。
%~ カレントディレクトリ。$HOME やそのサブディレクトリにいる場合、$HOME の部分は ~ に置き換えられます。
整形
%U [...] %u 下線表示の始まりと終わり
%B [...] %b 太字表示の始まりと終わり
%{ [...] %} 表示されない領域。色の設定をするときに使います。このタグによって Zsh はタグの中にあるものを全て無視します。使用しないとプロンプトの縁やインデントに妙な影響が出ることがあります。
カラー
$fg[color] 文字色を設定します (red, green, blue など - 太字デフォルト)。 Zsh は Bash とは違ったふうに色を設定します。色を使うには .zshrcPROMPT= の前に autoload -U colors && colors を追加してください。通常、カーソルが動かないように色の設定は %{ [...] %} の中に記述します。
$fg_no_bold[color] 太字でない文字色を設定します。
$fg_bold[color] 太字の文字色を設定します。
$reset_color 文字色をデフォルトの色に戻します。
利用できるカラー
black または 0 red または 1
green または 2 yellow または 3
blue または 4 magenta または 5
cyan または 6 white または 7
ノート: 太字の文字色は通常の文字色と必ずしも同じ色になるわけではありません。例えば、$fg['yellow'] は褐色や濃黄のようになりますが、$fg_bold['yellow'] はやや明るい普通の黄色のようになります。
サンプル

以下のようにすることで左右両側にプロンプトを表示できます:

PROMPT="%{$fg[red]%}%n%{$reset_color%}@%{$fg[blue]%}%m %{$fg_no_bold[yellow]%}%1~ %{$reset_color%}%#"
RPROMPT="[%{$fg_no_bold[yellow]%}%?%{$reset_color%}]"

次のようになります (色は省略):

username@host ~ %                                                         [0]

サンプル .zshrc ファイル

以下は .zshrc ファイルのリストです。自由に自分のファイルを追加してください:

ヒントとテクニック

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

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

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

多くのプログラムは端末の状態を変更し、異常終了時に端末の設定を復元しません (例:SIGINT がクラッシュまたは検出された場合)

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

$ reset

次の項では、端末を手動でリセットする必要を無くす方法について説明します。

ttyctl コマンド

ttyctl コマンドを使って端末を "フリーズ/フリーズ解除" することができます。起動時にインタラクティブシェルをフリーズするには、次のコマンドを使用します。

~/.zshrc
ttyctl -f

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

代替の線画文字セット は ttyctl が防ぐことのできない方法で端末を台無しにしてしまう可能性があります。

簡単な解決方法は、precmd フック関数から端末をリセットするエスケープシーケンスを出力し、プロンプトが表示される前に毎回実行されるようにすることです。例えば、 the escape sequence \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

## Remove duplicate entries
setopt PUSHD_IGNORE_DUPS

## This reverts the +/- operators.
setopt PUSHD_MINUS

使用する

$ dirs -v

cd -<NUM> を使用して、アクセスしたフォルダに移動。ダッシュの後にオートコンプリートを使用します。これは、オートコンプリートメニューを使用する場合に非常に便利です。

ノート: 複数の zsh の場合 セッションを開いていて、cd を実行しようとすると、両方のセッションで同じファイルへの書込みが競合するため、この操作は機能しません。

cdr

cdr を使用すると、作業ディレクトリーを、自動的に保守されるリストから前の作業ディレクトリーに変更することができます。セッション間および (デフォルトでは) 現在のセッション内の端末エミュレータ間で維持されるファイルに、すべてのエントリが格納されます。

セットアップ手順については、zshcontrib(1) § REMEMBERING RECENT DIRECTORIES を参照してください。

zoxide

zoxide は、よりスマートな cd コマンドで、わずか数回のキーストロークでどこにでも移動できます。頻繁に使用するディレクトリを記憶し、スコアリングメカニズムを使用して目的の場所を推測します。

ヘルプコマンド

Bash とは異なり、Zsh は組み込みコマンド help の代わりに run-help を提供します。デフォルトでは、run-helpman へのエイリアスとなっており、コマンドの前に付けて手動で実行するか、キーボードショートカット Alt+h または Esc 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) の代わりに man ページ git-commit(1) を開きます。

永続的な再ハッシュ

通常、compinit は $PATH 内で新しい実行可能ファイルを自動的には見つけません。たとえば、新しいパッケージをインストールした後、/usr/bin/ 内のファイルはすぐにまたは自動的には補完に含まれません。したがって、これらの新しい実行可能ファイルを含めるには、次のコマンドを実行します。

$ rehash

この 再ハッシュ は自動的に実行されるように設定できます。[1] zshrc に以下を含めるだけです。

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

オンデマンド再ハッシュ

しかし、上記のように pacmanhooks で設定すると、rehash を自動的に要求できます。これは、上記のような連続的な再ハッシュによるパフォーマンスの低下を招くことはありません。これを有効にするには、/etc/pacman.d/hooks ディレクトリと /var/cache/zsh フックファイルを作成します。

~/.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

precmd フックが /var/cache/zsh/pacman の更新前にトリガーされた場合、新しいプロンプトが開始されるまで完了できないことがあります。enter などの空のコマンドを実行すれば十分です。

SIGUSR1 を使用したオンデマンド再ハッシュの代替

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

/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 インスタンスが終了します。
~/.zshrc
TRAPUSR1() { rehash }

上記の 関数トラップ は、トラップのリスト trap 'rehash' USR1 で置き換えることができます。トラップのタイプの違いについては、zshmisc(1) § Trap Functions を参照してください。

このメソッドを使用すると、すべての rehash インスタンスが即座に zsh になり、precmd を起動するために Enter キーを押す必要がなくなります。

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 コマンドが見つかりません ハンドラー

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 の設定を管理するための、人気のあるコミュニティドリブンなフレームワークです。便利な関数、ヘルパー、プラグイン、テーマが山ほどバンドルされています。
  • Prezto - Instantly Awesome Zsh (AUR の prezto-gitAUR でインストール可能) は Zsh の設定フレームワークです。デフォルトでリッチなコマンドラインインターフェース環境を構築するモジュール・エイリアス・関数・自動補完・プロンプトテーマが付いています。
  • Zim (AUR の zsh-zim-gitAUR でインストール可能) は、驚異的な速度とモジュラー拡張機能を備えたZsh構成フレームワークです。

プラグインマネージャー

  • Antibody — Antigen に似たパフォーマンス重視のプラグインマネージャー
https://github.com/getantibody/antibody || antibodyAUR
  • zinit (previously "zplugin") — 柔軟で高速な Zsh プラグインマネージャー
http://github.com/zdharma/zinit || zsh-zplugin-gitAUR
  • zr — Rust で書かれたシンプルで高速なプラグインマネージャー
https://github.com/jedahan/zr || zr-gitAUR
  • sheldon — Rust で書かれた高速で柔軟なプラグインマネージャー
https://github.com/rossmacarthur/sheldon || sheldon-binAUR
  • zpm — キャッシュを生成し柔軟で高速なプラグインマネージャー
https://github.com/zpm-zsh/zpm || zpm-gitAUR
  • Antigen — oh-my-zsh と vundle に触発された Zsh のプラグインマネージャー ABANDONED
https://github.com/zsh-users/antigen || antigen-gitAUR
  • zgen — Zsh 用の軽量でシンプルなプラグインマネージャー ABANDONED
https://github.com/tarjoilija/zgen || zgen-gitAUR
  • zplug — Zsh 用の次世代プラグインマネージャー ABANDONED
https://github.com/zplug/zplug || zplugAUR

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

Fish には強力なシェルシンタックスハイライトとオートサジェスト機能があります。これを zsh で使うには、公式リポジトリから zsh-syntax-highlightingzsh-autosuggestions 両方もしくは必要な方一つをインストールして以下を zshrc に追加します:

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

"command not found" フック

pkgfile には、認識できないコマンドを入力したときに、自動的に公式リポジトリを検索する command_not_found_handler 関数を提供する Zsh スクリプトファイルが含まれています。

有効にするには、スクリプトを source する必要があります。例:

~/.zshrc
source /usr/share/doc/pkgfile/command-not-found.zsh
ノート: pkgfile データベースの更新が必要な場合があります。pkgfile#Installation で詳細をご確認ください。

参照