Zsh - Arch Linux 中文维基

跳至內容

# Zsh

出自 Arch Linux 中文维基
翻譯狀態：

- 本文（或部分內容）譯自 Zsh，最近一次同步於 2024-10-19，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

Zsh 是一款功能強大的命令行解釋器（shell），既可以作為交互式終端來使用，也可以作為腳本語言解釋器來使用。它在兼容 POSIX 的 sh 的同時（默認不兼容，僅在使用 `emulate sh` 時兼容），還改進了 Tab 補全和通配符等功能。

Zsh FAQ 說明了使用 Zsh 的更多原因。

## 安裝

在開始安裝之前，可以查看一下當前正在使用的 Shell 軟體：

    $ echo $SHELL

安裝 zsh包 包，也可以同時安裝 zsh-completions包 包以獲取更多命令補全規則。

### 初始配置

在終端裡面輸入以下命令，確保已經正確安裝了 Zsh：

    $ zsh

運行後你應該會看到zsh-newuser-install（新用戶安裝嚮導），它可以協助你完成一些基礎配置。如果要跳過這一步驟，可以按 `q` 退出。如果你沒有看到zsh-newuser-install，可以手動運行以下命令：

    $ autoload -Uz zsh-newuser-install
    $ zsh-newuser-install -f

注意：確保你的終端尺寸至少為 72×15 大小，否則zsh-newuser-install將無法運行。

### 將 Zsh 設為默認 Shell 軟體

將 Shell 改為 `/usr/bin/zsh`。參見命令行解釋器#更改默認_Shell。

提示：如果要替換 bash包，用戶可能希望能夠將 `~/.bashrc` 文件的某些代碼轉移到 `~/.zshrc` 文件（例如：命令提示符和別名），以及將 `~/.bash_profile` 文件的代碼轉移到 `~/.zprofile` 文件（例如：啟動 X Window System 的代碼）。

## 啟動/關閉文件

提示：有關交互式 shell 和登錄 shell 的解釋以及在啟動文件中放置內容的建議，請參閱 A User's Guide to the Z-Shell（Z-Shell 用戶指南，英文）。
注意：

- 如果未設置`$ZDOTDIR`，則使用`$HOME`。
- 如果在任何文件中取消設置`RCS`選項，那麼之後的配置文件將不會被讀取。
- 如果在任何文件中取消設置`GLOBAL_RCS`選項，那麼之後的全局配置文件（`/etc/zsh/*`）將不會被讀取。

在啟動時，Zsh 會按以下順序讀取這些文件（如果存在）：

- `/etc/zsh/zshenv` 用於設置所有用戶的環境變量。不應包含會產生輸出或假設 shell 連接到 TTY 的命令。此文件一旦存在就會被讀取，且無法跳過。
- `$ZDOTDIR/.zshenv` 用於設置用戶的環境變量。不應包含會產生輸出或假設 shell 連接到 TTY 的命令。此文件一旦存在就會被讀取。
- `/etc/zsh/zprofile` 在啟動為登錄 shell 時為所有用戶執行的命令。在 Arch Linux 中，此文件默認包含一行引入`/etc/profile`的代碼。在刪除該行之前，請參閱下方的警告！
  - `/etc/profile` 此文件應由所有符合 POSIX 標準的 shell 在登錄時引入，用於設置`$PATH`及其他環境變量，以及應用程式相關的設置（`/etc/profile.d/*.sh`）。
- `$ZDOTDIR/.zprofile` 在啟動為登錄 shell 時執行的用戶命令。通常用於自動啟動圖形會話和設置會話範圍的環境變量。
- `/etc/zsh/zshrc` 用於為所有用戶設置交互式 shell 的配置並執行命令，會在啟動為交互式 shell 時讀取。
- `$ZDOTDIR/.zshrc` 用於為用戶設置交互式 shell 配置並執行命令，會在啟動為交互式 shell 時讀取。
- `/etc/zsh/zlogin` 在初始進程結束時為所有用戶執行的命令，會在啟動為登錄 shell 時讀取。
- `$ZDOTDIR/.zlogin` 在初始進程結束時執行的用戶命令，會在啟動為登錄 shell 時讀取。通常用於自動啟動命令行工具，不應用於啟動圖形會話，因為此時會話可能包含僅適用於交互式 shell 的配置。
- `$ZDOTDIR/.zlogout` 在登錄 shell 退出時執行的用戶命令。
- `/etc/zsh/zlogout` 在登錄 shell 退出時為所有用戶執行的命令。

請參閱圖示說明（英文）。

注意：`$HOME/.profile`不是Zsh的啟動文件的一部分，除非 zsh 以`sh`或`ksh`模式運行並作為登錄 shell 啟動，否則不會被 zsh 引入。有關 sh 和 ksh（英語：ksh） 兼容模式的更多詳情，請參閱zsh(1) § COMPATIBILITY。
警告：不要刪除`/etc/zsh/zprofile`中的默認代碼，否則會破壞某些在`/etc/profile.d/`目錄下提供腳本的軟體包的完整性。

## 配置 Zsh

儘管 Zsh 開箱即用，但它的默認設置不符合大多數用戶的使用習慣。但由於 Zsh 有著大量自定義選項，配置 Zsh 可能是一項艱巨而耗時的體驗。有關自動配置，請參閱#第三方擴展。

### 簡單的 .zshrc

下面是一個示例配置文件。它提供了一組不錯的默認選項，並給出了許多可以自定義 Zsh 的方法的示例。要使用此配置，請將其保存為 `.zshrc`。

提示：運行 `source ~/.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（Z-Shell 用戶指南，英文）。

往`PATH`變量中添加`~/.local/bin/`：

    ~/.zshenv

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

### 命令補全

也許 Zsh 最引人注目的特性就是它先進的自動補全功能。至少，請在 `.zshrc` 中啟用自動完成功能。在 `~/.zshrc` 的最後加入下面的配置開啟自動補全：

    ~/.zshrc

    autoload -U compinit
    compinit

上面的補全配置包括 ssh/scp/sftp 命令中的主機名補全。但是要讓這個特性正常工作，不能啟用 ssh 的主機名散列（hash，即 ssh 客戶端配置中的 `HashKnownHosts` 選項）。

添加下面的配置可以啟動使用方向鍵控制的自動補全：

    ~/.zshrc

    zstyle ':completion:*' menu select

按兩次 `Tab` 啟動菜單

為了實現在特權命令中（例如，當你以 sudo 開始輸入一個命令時，補全腳本也會嘗試確定你可以用 sudo 完成的選項）對特權環境的自動補全，添加：

    ~/.zshrc

    zstyle ':completion::complete:*' gain-privileges 1

警告：這允許 Zsh 補全腳本以 sudo 權限運行命令。如果您使用不受信任的自動補全腳本，則不應啟用此功能。
注意：這種特殊的上下文感知補全僅適用於少數命令。

#### 自定義補全

可以自己編寫自定義補全，參考 zshcompsys(1) 手冊頁。

請注意，官方文檔可能難以閱讀，可以考慮嘗試更簡單的 zsh-completion-howto 教程（英文），以便輕鬆入門。

### 消除歷史記錄中的重複條目

    ~/.zshrc

    setopt HIST_IGNORE_DUPS

假如目前的歷史記錄中已經有重複條目，可以運行下面的命令清除

    $ sort -t ";" -k 2 -u ~/.zsh_history | sort -o ~/.zsh_history

### 快捷鍵綁定

Zsh 不使用 readline，而是使用其自身且更為強大的 Zsh 行編輯器（Zsh Line Editor，ZLE）。它不會讀取 `/etc/inputrc` 或 `~/.inputrc` 文件。閱讀 A closer look at the zsh line editor and creating custom widgets 以了解 ZLE 配置。

ZLE 有 Emacs 模式和 vi 模式。如果 `VISUAL` 和 `EDITOR` 環境變量之一包含字符串 `vi`，則會使用 vi 模式，否則默認為 Emacs 模式。可以分別使用 `bindkey -e` 或 `bindkey -v` 顯式指定 Emacs 模式和 vi 模式。在 vi 模式下按 Esc 鍵的延遲默認是 0.4 秒，你可以通過設置 `export KEYTIMEOUT=5` 將其縮短至 0.05 秒。

按鍵綁定是通過將與按鍵對應的一個轉義序列映射到一個 ZLE 小部件來分配的。可用的小部件及其作用描述和默認的按鍵綁定可以在 zshzle(1) § STANDARD WIDGETS 和 zshcontrib(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

這樣，當按下 `Up` 或 `Down` 鍵時，只會顯示與當前光標位置之前匹配的過去命令。

#### Shift、Alt、Ctrl 和 Meta 修飾鍵

xterm 兼容終端可以使用 user_caps(5) 中的擴展鍵定義，即 `Shift`、`Alt`、`Ctrl` 和 `Meta` 與 `Up`、`Down`、`Left`、`Right`、`PageUp`、`PageDown`、`Home`、`End` 或 `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]}" behind-word
    [[ -n "${key[Control-Right]}" ]] && bindkey -- "${key[Control-Right]}" front-word

#### 另一種方法

該方法會在啟動應用之前，將你的輸入保存在一行當中。

    ~/.zshrc

    ncmpcppShow() { ncmpcpp <$TTY; zle redisplay; }
    zle -N ncmpcppShow
    bindkey '^[\' ncmpcppShow

### 命令提示

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

    # 加載 promptinit
    autoload -Uz promptinit && promptinit

    # 定義主題
    prompt_mytheme_setup() {
    PS1="%~%# "
    }

    # 將主題添加到 promptsys
    prompt_themes+=( mytheme )

    # 加載主題
    prompt mytheme

### 自定義命令提示符

除了所有 shell 都通用的主要左側提示符 `PS1`（`PROMPT`、`prompt`）之外，Zsh 還支持右側提示符 `RPS1`（`RPROMPT`），這兩個變量可用於自定義。

其他特殊用途的提示符，例如 `PS2`（`PROMPT2`）、`PS3`（`PROMPT3`）、`PS4`（`PROMPT4`）、`RPS1`（`RPROMPT`）、`RPS2`（`RPROMPT2`）和 `SPROMPT`，在 zshparam(1) § PARAMETERS USED BY THE SHELL 中有說明。

所有提示符都可以使用提示符轉義進行自定義。可用的提示轉義列在 zshmisc(1) § EXPANSION OF PROMPT SEQUENCES 中。

#### 彩色

Zsh 設置顏色的方式與 Bash（英語：Bash/Prompt customization） 不同；您無需使用 terminfo(5) 中的大量 ANSI 轉義序列或終端功能。Zsh 提供了方便的提示轉義來設置前景色、背景色和其他視覺效果；請參閱 zshmisc(1) § Visual effects 以獲取它們的列表及其說明。

顏色可以使用十進制整數、八種最廣泛支持的顏色之一的名稱或十六進制格式的 # 後跟 RGB 三元組來指定。有關更多詳細信息，請參閱 zshzle(1) § CHARACTER HIGHLIGHTING 中 fg=colour 的描述。

命令 | 描述
--- | ---
`%F{color} [...] %f` | 和前面介紹的 $fg 是一樣的，但是更簡潔。還可以在 F 前面添加數字。
`$fg_no_bold[color]` | 設置文本為非粗體同時設定文本顏色
`$fg_bold[color]` | 設置文本為粗體同時設定文本顏色
`$reset_color` | 重置文本顏色（改為默認顏色）。不會重置粗體設定。使用 `%b` 來重置粗體設定。可以使用 `%f` 來簡化配置。
`%K{color} [...] %k` | 設置背景顏色。和非粗體文本顏色一樣。任何單一數字前綴會設置背景為黑色。

大多數終端支持以下英文顏色名稱作為代號：

中文名稱 | 英文名稱/代號 | 編號
--- | --- | ---
黑色 | `black` | `0`
紅色 | `red` | `1`
綠色 | `green` | `2`
黃色 | `yellow` | `3`
藍色 | `blue` | `4`
洋紅色 | `magenta` | `5`
青色 | `cyan` | `6`
白色 | `white` | `7`

注意： 粗體文本不一定會和普通文本使用同一種顏色。例如, `$fg['yellow']` 會使用暗一點的黃色, 而 `$fg_bold['yellow']` 可能會使用亮一點的黃色。（譯者註：具體是由你的終端模擬器配置決定的）

與 xterm 256 色兼容的終端模擬器的顏色編號 0–255 可在 xterm-256color 圖表中找到。

正確設置 TERM 環境變量後，可以使用 `echoti colors` 從 terminfo(5) 資料庫中找到終端支持的最大顏色數。對於 24 位顏色，還需使用 `print $COLORTERM` 檢查 COLORTERM 環境變量。如果它返回 `24bit` 或 `truecolor`，則即使 terminfo 顯示的數字較小，您的終端也支持 16777216（224）種顏色。

注意：

- 終端模擬器及其使用的配色方案之間的顏色 0–15 可能有所不同。
- 許多終端仿真器使用更亮的顏色顯示粗體。

提示：

- 可以使用命令 `print -P "prompt escapes"` 測試提示轉義，例如：

      $ print -P '%B%F{red}co%F{green}lo%F{blue}rs%f%b'

- 如果您使用 24 位顏色，您可能需要在不支持它們的終端中加載 `zsh/nearcolor` 模塊。例如：

      [[ "$COLORTERM" == (24bit|truecolor) || "${terminfo[colors]}" -eq '16777216' ]] || zmodload zsh/nearcolor

  有關 `zsh/nearcolor` 模塊的詳細信息，請參閱 zshmodules(1) § THE ZSH/NEARCOLOR MODULE。

#### 示例

簡單無色提示的示例：

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

顯示方式：

用戶名@主機 ~ %

帶顏色的左右雙面提示示例：

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

顯示方式如下：

用戶名@主機 ~ % [0]

要使用 16-255 範圍內的顏色和 24 位真彩色，您可以分別使用分配給所需顏色的 0 到 255 之間的數字及其十六進制顏色代碼：

    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 文件

- 要獲得與每月 ISO 版本（默認使用 Zsh）相同的設置，請安裝 grml-zsh-config包。它包括來自 grml 的許多調整和高級優化。
- https://github.com/MrElendig/dotfiles-alice/blob/master/.zshrc - 基本設置，帶有動態提示和窗口標題/硬信息。
- https://github.com/slashbeast/conf-mgmt/blob/master/roles/home_files/files/DOTzshrc - 具有多種功能的 zshrc，請務必查看其中的評論。值得注意的功能：確認功能以確保用戶想要運行關機、重啟或休眠，在提示中支持 GIT（無需 vcsinfo），帶菜單的制表符完成，將當前執行的命令列印到窗口的標題欄中等等。

請參閱 dotfiles#用戶倉庫了解更多。

## 提示與技巧

### 登錄時自動啟動 X

請參閱 xinit#登錄時自動啟動 X。

### 程序異常退出後恢復終端設置

許多程序會更改終端狀態，並且通常不會在異常退出時恢復終端設置（例如崩潰或遇到 SIGINT 時）。

這通常可以通過執行 reset(1) 來解決：

    $ reset

以下部分介紹了避免手動重置終端的方法。

#### ttyctl 命令

ttyctl 命令可用於「凍結/解凍」終端。要在啟動時凍結交互式 shell，請使用以下命令：

    ~/.zshrc

    ttyctl -f

#### 使用轉義序列重置終端

替代畫線字符集可能會以 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 可以配置 DIRSTACK 相關變量來加速 cd 訪問常用目錄。在你的配置文件中添加下面的配置：

    .zshrc

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

    DIRSTACKSIZE=20

    setopt autopushd pushdsilent pushdtohome

    ## Remove duplicate entries
    setopt pushdignoredups

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

現在你可以使用

    dirs -v

來列印目錄棧（dirstack）。使用 `cd -<NUM>` 來跳轉到以前訪問過的目錄。你還可以在連字符後面使用自動補全，非常方便。

注意：如果您打開了多個 zsh 會話並嘗試 `cd`，則此操作將不起作用，因為兩個會話在寫入同一個文件時會發生衝突。

#### cdr

cdr 允許您從自動維護的列表中將工作目錄更改為上一個工作目錄。它將所有條目存儲在跨會話維護的文件中，並且（默認情況下）在當前會話中的終端仿真器之間維護。

有關設置說明，請參閱 zshcontrib(1) § REMEMBERING RECENT DIRECTORIES。

#### zoxide

zoxide包 是一個更智能的 cd 命令，只需按幾下鍵，您就可以導航到任何地方。它會記住您經常使用的目錄，並使用評分機制來猜測您想要去的地方。

### 幫助命令

與 Bash 不同，Zsh 沒有內置的 `help` 命令，而是提供 `run-help`。默認情況下，`run-help` 是 `man` 的別名，可以通過將其添加到命令前面來手動執行，也可以使用鍵盤快捷鍵 `Alt+h` 或 `Esc` `h` 為當前輸入的命令調用它。

由於默認情況下它只是 man 的別名，因此它僅適用於外部命令。為了改進其功能，使其適用於 shell 內置命令和其他 shell 功能，您需要使用 `run-help` 函數。有關 `run-help` 及其輔助函數的更多信息，請參閱 zshcontrib(1)。

首先加載 `run-help` 函數，然後刪除現有的 `run-help` 別名。為了方便起見，可以將 `help` 別名為 `run-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` 命令現在將打開 man page git-commit(1)，而不是 git(1)。

### 持續 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` 的修改日期與上次安裝、升級或移除包的時間一致。然後，需要通過在你的 `~/.zshrc` 文件中添加以下內容來促使 `zsh` 在其命令緩存過期時 rehash：

    ~/.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 的行為是終止進程，所以當你第一次配置這個設置時，如果沒有加載下面的 trap，所有用戶的（包括登錄 shell）所有正在運行的 `zsh` 實例將終止。

    ~/.zshrc

    TRAPUSR1() { rehash }

上面的 trap 函數（function trap）可以用 trap 列表（list trap） `trap 'rehash' USR1` 替換。參見 zshmisc(1) § Trap Functions 了解不同類型的 trap 之間的區別。

這種方法將即時對所有 `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

### 文件管理器的快捷鍵綁定

圖形化文件管理器中使用快捷鍵可能很實用（譯者註：你也可以在 Zsh 中自定義快捷鍵達到這樣的效果）。第一個使用 `Alt+Left` 讓用戶撤銷最近的 cd 操作，第二個使用 `Alt+Up` 讓用戶進入上層目錄。這兩個快捷鍵同時也會顯示目錄中的內容。

    ~/.zshrc

    cdUndoKey() {
      popd      > /dev/null
      zle       reset-prompt
      echo
      ls
      echo
    }

    cdParentKey() {
      pushd .. > /dev/null
      zle      reset-prompt
      echo
      ls
      echo
    }

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

### xterm 標題

如果您的終端仿真器支持，您可以從 Zsh 設置其標題。這允許動態更改標題以顯示有關 shell 狀態的相關信息，例如顯示用戶名和當前目錄或當前正在執行的命令。

xterm 標題使用 xterm 控制序列作業系統命令 `\e]2;``\a` 或 `\e]2;``\e\\` 設置。例如：

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

將標題設置為

    My xterm title

獲得動態標題的一種簡單方法是在 `precmd` 和 `preexec` 鉤子函數中設置標題。有關可用鉤子函數及其說明的列表，請參閱 zshmisc(1) § Hook Functions。

通過使用 `print -P`，您還可以利用 Zsh 的提示轉義。

提示：

- 標題列印可以拆分為多個命令，只要它們是連續的即可。
- GNU Screen 將 xterm 標題發送到硬狀態 (`%h`)。如果您想使用 Screen 的 字符串轉義（例如用於顏色），您應該使用 `\e_``\e\\` 轉義序列設置硬狀態。否則，如果在 `\e]2;``\a` 中使用字符串轉義，終端仿真器將獲得亂碼標題，因為它無法解釋 Screen 的字符串轉義。

注意：

- 列印變量時不要使用 `print` 的 `-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{2}%n\005{-}@\005{5}%m\005{-} \005{+b 4}%~\005{-}\e\\'
    }

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

    if [[ "$TERM" == (Eterm*|alacritty*|aterm*|foot*|gnome*|konsole*|kterm*|putty*|rxvt*|screen*|wezterm*|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 的選項卡標題。

### Shell 環境檢測

請參閱有關 shell 環境檢測的存儲庫以了解檢測 shell 環境的測試。這包括登錄/交互式 shell、Xorg 會話、TTY 和 SSH 會話。

### /dev/tcp 等效項：ztcp

使用 `zsh/net/tcp` 模塊：

    $ zmodload zsh/net/tcp

您現在可以建立 TCP 連接：

    $ ztcp example.com 80

更多詳細信息請參閱 zshmodules(1) § THE_ZSH/NET/TCP_MODULE 和 zshtcpsys(1)。

### 在部分命令行上退出 shell 的快捷方式

默認情況下，如果命令行已填滿，`Ctrl+d` 將不會關閉您的 shell，這可以修復它：

    .zshrc

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

### pacman -F「未找到命令」處理程序

pacman 包含搜索包含文件的包的功能。以下命令未找到處理程序將在執行未知命令時直接使用 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: 未找到命令：%s\n' "$1"
        local entries=(
            ${(f)"$(/usr/bin/pacman -F --machinereadable -- "/usr/bin/$1")"}
        )
        if (( ${#entries[@]} ))
        then
            printf "${bright}$1${reset} 可能位於以下軟體包中：\n"
            local pkg
            for entry in "${entries[@]}"
            do
                # (存儲庫 軟體包 版本 文件)
                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
        return 127
    }
    ...

注意：pacman 的文件資料庫與普通同步資料庫是分開的，需要使用 `pacman -Fy` 來獲取。詳情請參閱 pacman#搜索包含特定文件的包。

有關使用 pkgfile 的替代方法，請參閱 #pkgfile「未找到命令」處理程序。

### 使用鍵綁定清除後緩衝區

默認情況下，清除屏幕鍵綁定不會清除大多數終端仿真器上的後緩衝區（您需要向上滾動才能看到的部分）。此問題的一個可能解決方案如下：

    ~/.zshrc

    ...
    function clear-screen-and-scrollback() {
        printf '\x1Bc'
        zle clear-screen
    }

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

## 第三方擴展

### 配置框架

注意：框架引入了一定程度的抽象和複雜性。它們可以並且經常會引入未定義的行為。如果 shell 出現故障，則「第一個」調試步驟應該是恢復到普通 shell。

- oh-my-posh — Oh My Posh 是任何 shell 的自定義提示引擎，它能夠使用函數或變量調整提示字符串。

  https://github.com/JanDeDobbeleer/oh-my-posh || oh-my-poshAUR

- oh-my-zsh — 一個流行的、社區驅動的框架，用於管理您的 Zsh 配置。它捆綁了大量有用的函數、幫助程序、插件和主題。

  https://github.com/ohmyzsh/ohmyzsh || oh-my-zsh-gitAUR

- Prezto — Zsh 的配置框架。它帶有模塊，通過合理的默認值、別名、函數、自動完成和提示主題豐富了命令行界面環境。

  https://github.com/sorin-ionescu/prezto || prezto-gitAUR

- ZIM — 具有極快速度和模塊化擴展的配置框架。Zim 非常易於定製，並且帶有一組豐富的模塊和功能，而不會影響速度或功能。

  https://github.com/zimfw/zimfw || zsh-zim-gitAUR

### 插件管理器

- Antidote — 功能齊全的 Zsh 舊版 Antibody 插件管理器實現。

  https://github.com/mattmc3/antidote || zsh-antidoteAUR

- zinit（原「zplugin」) — 靈活的 Zsh 插件管理器，具有乾淨的 fpath、報告、完成管理、渦輪模式 REVIVED

  https://github.com/zdharma-continuum/zinit || zinitAUR

- zi（原「zplugin」） — zplugin 的替代分支，旨在擴展原始項目，而不是像 zinit 那樣保存和維護原始項目。

  https://github.com/z-shell/zi || 未被打包？在 AUR 裡搜索

- sheldon — 快速、可配置的 shell 插件管理器，用 Rust 編寫 [4]

  https://github.com/rossmacarthur/sheldon || sheldon包

- Antigen — Zsh 的插件管理器，靈感來自 oh-my-zsh 和 vundle。 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 是一款比較新的終端軟體

Fish 提供了非常強大的命令高亮。如果你希望在 zsh 中使用類似的功能，你可以安裝 zsh-syntax-highlighting包、zsh-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「未找到命令」處理程序

pkgfile 包含一個 Zsh 腳本文件，該文件提供了一個 `command_not_found_handler` 函數，該函數將在輸入無法識別的命令時自動搜索 pkgfile 資料庫。

您需要 source 該腳本才能啟用它。例如：

    ~/.zshrc

    source /usr/share/doc/pkgfile/command-not-found.zsh

注意：可能需要更新 pkgfile 資料庫才能正常工作。有關詳細信息，請參閱 pkgfile#安裝。

有關使用 pacman 本機功能的替代方法，請參閱 #pacman -F「未找到命令」處理程序。

## 卸載

在卸載 zsh包 之前請先更換默認終端。

警告：如果不遵循下面的步驟可能會導致用戶無法訪問任何終端

運行下面的命令：

    $ chsh -s /bin/bash user

每一個使用 zsh 作為默認終端的用戶都需要執行一遍條命令。當完成之後就可以把 zsh包 軟體包刪除了。

當然你也也可以以 root 身份修改 `/etc/passwd` 文件，來批量更改用戶的默認終端。

警告：強烈建議使用 `vipw` 來修改 `/etc/passwd`，因為它可以幫助你消滅格式錯誤

例如將下面的配置中的 /bin/zsh

    username:x:1000:1000:Full Name,,,:/home/username:/bin/zsh

改成 /bin/bash

    username:x:1000:1000:Full Name,,,:/home/username:/bin/bash

## 另請參見

- zhwp:Zsh
- An Introduction to the Z Shell
- A User's Guide to ZSH
- The Z Shell Manual（可用的不同格式）
- Zsh FAQ
- zsh-lovers(1)（可通過zsh-lovers包使用）
- Gentoo: Zsh/Guide
- Bash2Zsh Reference Card

分類：​

- 命令行解釋器
- Pages with missing package links

隱藏分類：​

- 有藍鏈卻未移除內部連結助手模板的頁面

Zsh
新增話題