Zsh

出自 Arch Linux 中文维基

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 軟件英語Command-line shell#Changing your default shell

提示:如果要替換 bash,用户可能希望能夠將 ~/.bashrc 文件的某些代碼轉移到 ~/.zshrc 文件(例如:命令行提示符和別名),以及將 ~/.bash_profile 文件的代碼轉移到 ~/.zprofile 文件(例如:啟動 X Window System 的代碼)。

配置文件介紹[編輯 | 編輯原始碼]

當 Zsh 啟動時,它會按照順序依次讀取下面的配置文件:

/etc/zsh/zshenv
該文件應該包含用來設置PATH 環境變量以及其他一些環境變量的命令;不應該包含那些可以產生輸出結果或者假設終端已經附着到 tty 上的命令。
~/.zshenv
該文件和 /etc/zsh/zshenv 相似,但是它是針對每個用户而言的。一般來説是用來設置一些有用的環境變量。
/etc/zsh/zprofile
這是一個全局的配置文件,在用户登錄的時候加載。一般是用來在登錄的時候執行一些命令。請注意,在 Arch Linux 裡該文件默認包含一行配置,用來加載 /etc/profile 文件,詳見 #全局配置文件
/etc/profile
在登錄時,該文件應該被所有和伯克利(Bourne)終端相兼容的終端加載:它在登錄的的時候會加載應用相關的配置(/etc/profile.d/*.sh)。注意在 Arch Linux 裡,Zsh 會默認加載該文件。
~/.zprofile
該文件一般用來在登錄的時候自動執行一些用户腳本。
/etc/zsh/zshrc
當 Zsh 被作為交互式終端的時候,會加載這樣一個全局配置文件。
~/.zshrc
當 Zsh 被作為交互式終端的時候,會加載這樣一個用户配置文件。
/etc/zsh/zlogin
在登錄完畢後加載的一個全局配置文件。
~/.zlogin
/etc/zsh/zlogin 相似,但是它是針對每個用户而言的。
/etc/zsh/zlogout
在註銷的時候被加載的一個全局配置文件。
~/.zlogout
/etc/zsh/zlogout 相似,但是它是針對每個用户而言的.
注意:
  • 在 Arch 源中的 zsh 所使用的文件路徑和 Zsh 的 man 手冊中默認的不同(詳見 #全局配置文件
  • /etc/profile 不是 Zsh 常規啟動配置文件的一部分,但是 Arch 源中的 zsh 會在 /etc/zsh/zprofile 裏面加載它。用户應該注意 /etc/profile 裏面設置的 $PATH 環境變量會覆蓋掉 ~/.zshenv 裏面配置的任何 $PATH。為了防止這一點,請在 ~/.zshrc 當中設置 $PATH(不推薦替換掉 /etc/zsh/zprofile 裏面的默認配置,因為這樣會破壞其他提供了 /etc/profile.d 的軟件包和 Zsh 的聯動關係)

全局配置文件[編輯 | 編輯原始碼]

有時候你可能想提供一些所有 Zsh 用户共享的配置。在幫助手冊 zsh(1) 提到的一些全局配置文件(例如 /etc/zshrc)的路徑,在 Arch Linux 裡是有一些不同的,因為其路徑已經被編譯為 [1] /etc/zsh/

所以,Arch 源中 zsh 的全局配置文件會使用 /etc/zsh/zshrc 而不是 /etc/zshrc。類似的還有 /etc/zsh/zshenv/etc/zsh/zlogin/etc/zsh/zlogout。注意這些文件不是默認就被創建好的,你可以根據需要來創建它們。

唯一的例外是 zprofile,請使用 /etc/profile

配置 Zsh[編輯 | 編輯原始碼]

儘管 Zsh 基本不需要怎麼配置就能滿足大多數用户的需求,但是因為其中包含太多的可定製選項,導致配置 Zsh 可能會比較耗時。

簡單的 .zshrc[編輯 | 編輯原始碼]

下面是一個簡單的 .zshrc 配置文件,它提供一個配置 Zsh 的生動的例子。你可以將下面的配置保存為文件 .zshrc 來使用它。

~/.zshrc
autoload -U compinit promptinit
compinit
promptinit

# 設置 walters 主題的默認命令行提示符
prompt walters
提示:你可以執行命令 source ~/.zshrc 來生效修改的配置,而不需要重新登錄

配置 $PATH[編輯 | 編輯原始碼]

將下面的配置放到 ~/.zshenv 中:

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

另請參見 《A User's Guide to the Z-Shell(Z-Shell 用户指南)》#配置 Zsh 中的相關內容。

命令補全[編輯 | 編輯原始碼]

也許 Zsh 最引人注目的特性就是它先進的自動補全功能。在 ~/.zshrc 最後加入下面的配置,開啟自動補全:

~/.zshrc
autoload -U compinit
compinit

上面的補全配置包括 ssh/scp/sftp 命令中的主機名(host name)補全。但是要讓這個特性正常工作,你需要防止 ~/.ssh/known_hosts 中的主機名被散列化(hash)。

警吿: 主機名去散列化可能會導致本機成為 跳躍式攻擊("Island-hopping" attacks)的跳板。如果你希望 Zsh 自動補全主機名,你可以註釋掉 /etc/ssh/ssh_config 當中的這行配置,或者設置為 no
/etc/ssh/ssh_config
#HashKnownHosts yes

你可以將原來的 ~/.ssh/known_hosts 移動到別的地方,之後 ssh 創建的 ~/.ssh/known_hosts 文件就不會散列化主機名(但是之前信任的主機如果需要,還得重新導入進來)。具體請參考 ssh 的 README 文件中散列化主機名的相關內容。

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

~/.zshrc
zstyle ':completion:*' menu select
按兩次 tab 鍵啟動菜單

添加下面的配置可以啟動命令行別名的自動補全:

~/.zshrc
setopt completealiases

"command not found" 鈎子[編輯 | 編輯原始碼]

另請參見 Pkgfile#Command not found

消除歷史記錄中的重複條目[編輯 | 編輯原始碼]

~/.zshrc
setopt HIST_IGNORE_DUPS

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

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

ttyctl 命令[編輯 | 編輯原始碼]

[2] 描述了 Zsh 中的 ttyctl 命令。它可以用來鎖定/解鎖(freeze/unfreeze)終端。許多程序會修改終端的狀態並且在異常退出的時候不會還原初始狀態。下面的配置可以避免手動重置終端。

~/.zshrc
ttyctl -f

快捷鍵綁定[編輯 | 編輯原始碼]

Zsh 使用自帶的 zle 代替 readline,並且不會讀取 /etc/inputrc 或者 ~/.inputrc。 Zle 有 emacsvi 兩個模式,默認情況下它根據環境變量 $EDITOR 來決定使用哪一個模式,如果為空默認為 emacs 模式。使用 bindkey -e 或者 bindkey -v 來手動指定模式。 另請參見 zshwiki: bindkeys.

ncurses 應用的快捷鍵綁定[編輯 | 編輯原始碼]

(譯者註:ncurses 是一個字符界面下的 GUI 框架)如果直接將 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

查找歷史記錄[編輯 | 編輯原始碼]

~/.zshrc
[[ -n "${key[PageUp]}"   ]]  && bindkey  "${key[PageUp]}"    history-beginning-search-backward
[[ -n "${key[PageDown]}" ]]  && bindkey  "${key[PageDown]}"  history-beginning-search-forward

使用這段配置會只顯示以當前命令開頭的歷史記錄。

命令提示符[編輯 | 編輯原始碼]

這是一種 Zsh 中簡單快速設置彩色提示符的方法。首先確保 .zshrc 中配置了自動加載提示符。具體配置如下:

~/.zshrc
autoload -U promptinit
promptinit

然後你可以運行下面的命令查看可用的提示符:

$ prompt -l

使用下面命令來啟動其中一種提示符,例如啟動 "walters" 提示符:

$ prompt walters

使用下面的命令查看所有可用的主題:

$ prompt -p

自定義命令提示符[編輯 | 編輯原始碼]

對於那些不滿足默認提示符的用户,Zsh 提供了自定義提示符的方法。除了普通終端會提供的靠左的提示符外,Zsh 還提供了靠右的提示符。通過配置 PROMPT= 來設置。

可以參考 Prompt Expansion 來獲得所有可用的 prompt variables 和 conditional substrings。

彩色[編輯 | 編輯原始碼]

Zsh 設置彩色提示符的方法和 Bash 不同。 在 .zshrcPROMPT= 前面添加 autoload -U colors && colors 來啟用彩色提示符。通常你需要將這些配置放在 %{ [...] %} 裏面確保光標不移動。

$fg[color] 會設置文本的顏色(紅,綠,藍,等等。默認是和之前的文本顏色保持一致)

命令 描述
%F{color} [...] %f 和前面介紹的 $fg 是一樣的,但是更簡潔。還可以在 F 前面添加數字。
$fg_no_bold[color] 設置文本為非粗體同時設定文本顏色
$fg_bold[color] 設置文本為粗體同時設定文本顏色
$reset_color 重置文本顏色(改為默認顏色)。不會重置粗體設定。使用 %b 來重置粗體設定。可以使用 %f 來簡化配置。
%K{color} [...] %k 設置背景顏色。和非粗體文本顏色一樣。任何單一數字前綴會設置背景為黑色。
Possible color values
black or 0 red or 1
green or 2 yellow or 3
blue or 4 magenta or 5
cyan or 6 white or 7
注意: 粗體文本不一定會和普通文本使用同一種顏色。例如, $fg['yellow'] 會使用暗一點的黃色, 而 $fg_bold['yellow'] 可能會使用亮一點的黃色。(譯者註:具體是由你的終端模擬器配置決定的)

示例[編輯 | 編輯原始碼]

左右雙邊的提示符:

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

效果如下(忽略顏色):

username@host ~ %                                                         [0]

目錄棧(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> 來跳轉到以前訪問過的目錄。你還可以在連字符後面使用自動補全,非常方便。

幫助命令[編輯 | 編輯原始碼]

bash 不同的是 zsh 沒有內置的 help 命令,要想在 zsh 中使用 help,可以添加下面的配置:

autoload -U run-help
autoload run-help-git
autoload run-help-svn
autoload run-help-svk
unalias run-help
alias help=run-help

仿 Fish 命令高亮[編輯 | 編輯原始碼]

(譯者註:Fish 是一款比較新的終端軟件)Fish 提供了非常強大的命令高亮。如果你希望在 zsh 中使用類似的功能,你可以從官方倉庫裡安裝 zsh-syntax-highlighting,然後添加下面的配置到你的 zshrc 中:

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

.zshrc 樣例[編輯 | 編輯原始碼]

配置框架[編輯 | 編輯原始碼]

  • oh-my-zsh 是一個著名的,社區驅動的框架,它擁有很多有用的函數,helpers,插件,主題,可以用來簡化複雜的 Zsh 配置。
  • Prezto - Instantly Awesome Zsh(可以通過 prezto-gitAUR 獲取) 它是一個模塊化的 Zsh 配置框架,裏面有很多順手的默認配置、別名、函數、自動補全和命令提示符主題。
  • Antigen (可以通過 antigen-gitAUR 獲取) 這個一個 zsh 插件管理器,受到 oh-my-zsh 和 vundle 的啟發

自啟動程序[編輯 | 編輯原始碼]

注意: $ZDOTDIR 默認指向 $HOME

Zsh 經常執行 /etc/zsh/zshenv$ZDOTDIR/.zshenv,所以不要讓他們變得很臃腫。

如果是一個登錄了的終端,會加載 /etc/profile 然後加載 $ZDOTDIR/.zprofile。然後如果是交互式模式,會繼續加載 /etc/zsh/zshrc 接着加載 $ZDOTDIR/.zshrc 。最後如果還是登錄了的終端,/etc/zsh/zlogin$ZDOTDIR/.zlogin 也會被加載。

另請參見 zsh(1)STARTUP/SHUTDOWN FILES 章節。

刷新自動補全[編輯 | 編輯原始碼]

一般來説,compinit 不會自動在 $PATH 裏面查找新的可執行文件。例如當你安裝了一個新的軟件包,/usr/bin 裡的新文件不會立即自動添加到自動補全當中。所以你需要執行下面的命令來將它們添加進自動補全:

$ rehash

這個 'rehash' 可以被放到你的 zshrc 來自動執行

~/.zshrc
zstyle ':completion:*' rehash true
注意: 這個技巧在 Oh My Zsh [3] 的一次 PR 中被發現

卸載[編輯 | 編輯原始碼]

在卸載 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

另請參見[編輯 | 編輯原始碼]