Zsh
Zsh 是一个强大的 Shell,既可以作为交互式 Shell,也可以作为脚本语言解释器。虽然兼容 POSIX sh (默认不兼容,只有在执行 emulate sh 时才会兼容),但它提供了诸如改进的 标签补全 和 globbing 等优点。
Zsh FAQ 提供了更多使用 Zsh 的理由。
安装
开始之前,用户可能想知道当前正在使用的 Shell 是什么
$ echo $SHELL
安装 zsh 包。为了获得额外的补全定义,也请安装 zsh-completions 包。
初始配置
通过在终端中运行以下命令,确保 Zsh 已正确安装:
$ zsh
您现在应该会看到 zsh-newuser-install,它将引导您完成一些基本配置。如果您想跳过它,请按 q。如果您没有看到它,可以手动调用:
$ autoload -Uz zsh-newuser-install $ zsh-newuser-install -f
将 Zsh 设置为默认 Shell
将您的 Shell 更改为 /usr/bin/zsh。请参阅 Command-line shell#Changing your default shell。
~/.bashrc 移动到 ~/.zshrc (例如提示符和 别名),并将一些代码从 ~/.bash_profile 移动到 ~/.zprofile (例如 启动 X Window System 的代码)。启动/关闭文件
- 如果未设置
$ZDOTDIR,则使用$HOME作为替代。 - 如果在任何文件中取消设置了
RCS选项,则在该文件之后将不再读取任何配置文件。 - 如果在任何文件中取消设置了
GLOBAL_RCS选项,则在该文件之后将不再读取任何全局配置文件 (/etc/zsh/*)。
启动时,Zsh 默认将按以下顺序从以下文件中读取命令,前提是它们存在。
/etc/zsh/zshenv用于为所有用户设置 环境变量;它不应包含产生输出或假定 Shell 已连接到 TTY 的命令。当此文件存在时,它将 *始终* 被读取,此行为无法覆盖。$ZDOTDIR/.zshenv用于设置用户的环境变量;它不应包含产生输出或假定 Shell 已连接到 TTY 的命令。当此文件存在时,它将 *始终* 被读取。/etc/zsh/zprofile用于在启动时为所有用户执行命令,将在启动为 *登录 Shell* 时读取。请注意,在 Arch Linux 上,默认情况下它包含 一行,该行会 sourced/etc/profile。在想要删除它之前,请注意以下警告!/etc/profile此文件应由所有 POSIX sh 兼容 Shell 在登录时 sourced;它会在登录时设置$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 启动,否则 **不会被 sourced**。有关 sh 和 ksh 兼容模式的更多详细信息,请参阅 zsh(1) § COMPATIBILITY。配置 Zsh
尽管 Zsh 开箱即用,但它几乎肯定没有设置为大多数用户期望的方式。但由于 Zsh 可用的定制量巨大,配置 Zsh 可能是一项艰巨且耗时的任务。有关自动配置,请参阅 #第三方扩展。
简单的 .zshrc
下面包含一个示例配置文件。它提供了相当不错的默认选项集,并举例说明了 Zsh 可以定制的许多方式。为了使用此配置,请将其保存为名为 .zshrc 的文件。
source ~/.zshrc,可以在无需注销再登录的情况下应用更改。这是一个简单的 .zshrc
~/.zshrc
autoload -Uz compinit promptinit compinit promptinit # This will set the default prompt to the walters theme 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 键以激活菜单。
要为特权命令启用特权环境的自动补全 (例如,如果您补全的命令以 sudo 开头,补全脚本也将尝试使用 sudo 来确定您的补全),请包含:
~/.zshrc
zstyle ':completion::complete:*' gain-privileges 1
自定义补全
您可以自己编写自定义补全。如果这样做,可以参考 zshcompsys(1) 手册页。
请注意,官方文档可能难以阅读。您可以尝试更简单的 zsh-completion-howto 教程,以便轻松入门。
按键绑定
Zsh 不使用 readline,而是使用自己更强大的 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
# create a zkbd compatible hash;
# to add other keys to this hash, see: 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]}"
# 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[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
# 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
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
通过这样做,当按下 向上 或 向下 键时,只会显示与当前光标位置之前到当前行匹配的历史命令。
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]}" 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
自定义提示符
除了所有 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 不同;您无需使用大量的 ANSI 转义序列或来自 terminfo(5) 的终端功能。Zsh 提供了方便的提示符转义字符来设置前景色、背景色和其他视觉效果;有关它们及其描述的列表,请参阅 zshmisc(1) § Visual effects。
颜色 可以使用十进制整数、八种最广泛支持的颜色之一的名称,或以 # 开头后跟十六进制格式的 RGB 三元组来指定。有关 fg=colour 的更多详细信息,请参阅 zshzle(1) § CHARACTER HIGHLIGHTING。
大多数终端支持以下颜色名称:
| 名称 | 编号 |
|---|---|
黑色 |
0
|
红色 |
1
|
绿色 |
2
|
黄色 |
3
|
蓝色 |
4
|
品红色 |
5
|
青色 |
6
|
白色 |
7
|
兼容 xterm 256 色的终端的颜色编号 0-255 可以在 xterm-256color 图表 中找到。
使用正确设置的 TERM 环境变量,可以使用 echoti colors 命令从 terminfo(5) 数据库中查找终端支持的最大颜色数。对于 24 位颜色,还应检查 COLORTERM 环境变量,执行 print $COLORTERM。如果它返回 24bit 或 truecolor,则您的终端支持 16777216 (224) 种颜色,即使 terminfo 显示的数量较少。
- 颜色 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]'
下面是它的显示效果
要使用 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 - 基本设置,带有动态提示符和窗口标题/硬信息。
有关更多信息,请参阅 dotfiles#User repositories。
技巧与提示
登录时自动启动 X
请参阅 xinit#Autostart X at login。
程序异常退出后恢复终端设置
许多程序会改变终端状态,并且在异常退出时 (例如崩溃或遇到 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 可以配置为记住 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
来打印 dirstack。使用 cd -<NUM> 返回到访问过的文件夹。在连字符后使用自动补全。当使用自动补全菜单时,这非常有用。
- 当有多个 zsh 会话打开并尝试
cd时,这将无效,因为两个会话会写入同一文件,从而导致冲突。 - 您可能需要创建
$HOME/.cache/zsh目录,以避免出现no such file or directory错误。
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 可以通过 hooks 配置以自动请求 rehash,这样就不会像上面那样产生持续 rehash 的性能损失。要启用此功能,请创建 /etc/pacman.d/hooks 目录和 /var/cache/zsh 目录,然后创建一个 hook 文件:
/etc/pacman.d/hooks/zsh-rehash.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
如果 precmd 钩子在 /var/cache/zsh/pacman 更新之前触发,则在启动新提示符之前可能无法使用补全。运行一个空命令,例如按 Enter 键,应该就足够了。
使用 SIGUSR1 的替代按需 rehash
同上,但 hook 文件如下所示:
/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 的默认行为是终止,因此当您首次配置此功能时,所有正在运行的 zsh 实例 (包括登录 Shell) 将终止,如果它们没有 sourced 下面的 trap 的话。~/.zshrc
TRAPUSR1() { rehash }
上面的 function trap 可以替换为 list trap trap 'rehash' USR1。有关 trap 类型之间的差异,请参阅 zshmisc(1) § Trap Functions。
此方法将立即 rehash 所有 zsh 实例,无需按 Enter 键触发 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
文件管理器按键绑定
像图形文件管理器中使用的按键绑定可能会很有用。第一个返回到目录历史记录 (Alt+Left),第二个让用户转到父目录 (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 设置其标题。这允许动态更改标题以显示有关 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 标题发送到 hardstatus (
%h)。如果您想使用 Screen 的 字符串转义 (例如用于颜色),则应使用\e_\e\\转义序列来设置 hardstatus。否则,如果\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
终端模拟器标签页标题
某些终端模拟器和多路复用器支持设置标签页标题。转义序列取决于终端:
| Terminal | 转义序列 | 描述 |
|---|---|---|
| GNU Screen | \ek\e\\ |
Screen 的窗口标题 (%t)。 |
| Konsole | \e]30;\a |
Konsole 的标签页标题。 |
Shell 环境检测
有关检测 Shell 环境的测试,请参阅 shell-environment-detection 仓库。这包括登录/交互式 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 "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
return 127
}
...
pacman -Fy 来获取。有关详细信息,请参阅 pacman#Querying package databases。有关使用 pkgfile 的替代方案,请参阅 #pkgfile "command not found" handler。
使用按键绑定清除后缓冲区
默认情况下,清除屏幕的按键绑定在大多数终端模拟器上不会清除后缓冲区 (您需要向上滚动才能看到的部分)。可能的解决方案如下。
~/.zshrc
...
function clear-screen-and-scrollback() {
printf '\x1Bc'
zle clear-screen
}
zle -N clear-screen-and-scrollback
bindkey '^L' clear-screen-and-scrollback
...
第三方扩展
配置框架
- oh-my-posh — Oh My Posh 是一个自定义提示符引擎,适用于任何能够通过函数或变量调整提示符字符串的 Shell。
- oh-my-zsh — 一个流行的、社区驱动的 Zsh 配置管理框架。它捆绑了大量有用的函数、助手、插件和主题。
- Prezto — 一个 Zsh 的配置框架。它带有模块,通过合理的默认设置、别名、函数、自动补全和提示主题来丰富命令行界面环境。
- ZIM — 一个具有极速和模块化扩展的配置框架。Zim 非常易于定制,并提供了一套丰富的模块和功能,同时不牺牲速度或功能。
插件管理器
- Antidote — 遗留的 Antibody 插件管理器的功能齐全的 Zsh 实现。
- zinit (以前称为 "zplugin") — 灵活的 Zsh 插件管理器,具有干净的 fpath、报告、补全管理、涡轮模式 已恢复
- zi (以前称为 "zplugin") — zplugin 的替代分支,旨在扩展原始项目,而不是像 zinit 那样保留和维护原始项目。
- sheldon — 快速、可配置的 Shell 插件管理器,用 Rust 编写 [4]
- Antigen — Zsh 的插件管理器,受 oh-my-zsh 和 vundle 启发。 已放弃
- zgen — Zsh 的轻量级简单插件管理器。 已放弃
- zplug — Zsh 的下一代插件管理器。 已放弃
类似 Fish 的语法高亮和自动建议
Fish 提供了非常强大的 Shell 语法高亮和自动建议。要在 Zsh 中同时使用它们,您可以安装 zsh-syntax-highlighting、zsh-autosuggestions,最后在您的 zshrc 文件末尾 source 一个或两个提供的脚本,确保 zsh-syntax-highlighting 在 zsh-autosuggestions 之后 [5]
~/.zshrc
source /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
pkgfile "command not found" 处理程序
pkgfile 包含一个 Zsh 脚本文件,该文件提供了一个 command_not_found_handler 函数,当输入一个无法识别的命令时,它将自动搜索 pkgfile 数据库。
您需要 source 该脚本才能启用它。例如:
~/.zshrc
source /usr/share/doc/pkgfile/command-not-found.zsh
对于使用 pacman 原生功能来实现相同目的的替代方法,请参阅 #pacman -F "command not found" handler。
故障排除
IOT 指令
IOT instruction 消息仅表示应用程序因信号 6 (SIGABRT, Signal Abort) 而退出。此 补丁 已经包含在主线(即您可以使用 zsh-gitAUR)中,并且将在 5.10 版本中应用。有关更多信息,请参阅 [6]、[7] 和 signal(7) § Standard signals。
参见
- 维基百科:Zsh
- Z Shell 入门指南
- ZSH 用户指南
- Z Shell 手册(有不同格式的 这里 可用)
- Zsh FAQ
- zsh-lovers(1)(可作为 zsh-lovers 包使用)
- Gentoo: Zsh/Guide
- Bash2Zsh 参考卡