Zsh

出自 ArchWiki
(重定向自 Zshrc

Zsh 是一个强大的 shell,它既可以作为交互式 shell 运行,也可以作为脚本语言解释器。虽然它与 POSIX sh 兼容(默认情况下不兼容,只有在执行 emulate sh 时才兼容),但它提供了诸如改进的制表符补全通配符展开等优点。

Zsh FAQ 提供了更多使用 Zsh 的理由。

安装

在开始之前,用户可能想查看当前正在使用的 shell

$ 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 设置为默认 Shell

将您的 shell 更改为 /usr/bin/zsh。请参阅 命令行 shell#更改您的默认 shell

提示: 如果替换 bash,用户可能希望将一些代码从 ~/.bashrc 移动到 ~/.zshrc(例如,提示符和别名),以及从 ~/.bash_profile 移动到 ~/.zprofile(例如,启动 X 窗口系统的代码)。

启动/关闭文件

提示: 有关交互式 shell 和登录 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 上,默认情况下,它包含一行,该行会 source /etc/profile。在想要删除该行之前,请参阅下面的警告!
    • /etc/profile 此文件应在登录时由所有 POSIX sh 兼容的 shell sourcing:它会在登录时设置 $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 作为 shksh 调用并作为登录 shell 启动,否则不会被 sourcing。有关 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

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

有关提示符主题系统的更多详细信息,请参阅#提示符主题

配置 $PATH

Zsh 将 PATH 变量绑定到一个 path 数组。这允许您通过简单地修改 path 数组来操作 PATH。有关详细信息,请参阅 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
警告: 这将允许 Zsh 补全脚本以 sudo 权限运行命令。如果您使用不受信任的自动补全脚本,则不应启用此功能。
注意: 这种特殊的上下文感知补全仅适用于少量命令。

自定义补全

您可以自行编写自定义补全。如果您这样做,您可以参考 zshcompsys(1) 手册页。

请注意,官方文档可能难以阅读。您可以考虑尝试更简单的 zsh-completion-howto 教程,以便轻松入门。

快捷键绑定

Zsh 不使用 readline,而是使用其自身更强大的 Zsh Line Editor (ZLE)。它不读取 /etc/inputrc~/.inputrc。请阅读 深入了解 zsh 行编辑器和创建自定义小部件,以了解 ZLE 配置的入门知识。

ZLE 具有 Emacs 模式和 vi 模式。如果 VISUALEDITOR 环境变量 之一包含字符串 vi,则将使用 vi 模式;否则,它将默认为 Emacs 模式。使用 bindkey -ebindkey -v 分别显式设置 Emacs 模式或 vi 模式。vi 模式下按 Esc 键的延迟默认为 0.4 秒,您可以使用 export KEYTIMEOUT=5 将其缩短(0.05 秒)。

键位绑定通过将与按键匹配的转义序列映射到 ZLE 小部件来分配。 可用的小部件及其操作描述和默认键位绑定在 zshzle(1) § STANDARD WIDGETSzshcontrib(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

通过这样做,当按下 UpDown 键时,只会显示与当前行(直到当前光标位置)匹配的过去命令。

Shift、Alt、Ctrl 和 Meta 修饰键

xterm 兼容终端可以使用 user_caps(5) 中的扩展键定义。 这些是 ShiftAltCtrlMetaUpDownLeftRightPageUpPageDownHomeEndDel 的组合。 有关修饰键和组合键的推荐名称列表,请参阅 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 三元组来指定。 有关更多详细信息,请参阅 zshzle(1) § CHARACTER HIGHLIGHTING 中 fg=colour 的描述。

大多数终端都按名称支持以下颜色

名称 数字
黑色 0
红色 1
绿色 2
黄色 3
蓝色 4
品红色 5
青色 6
白色 7

与 xterm 256 色兼容的终端模拟器的颜色编号 0–255 可以在 xterm-256color 图表中找到。

在正确设置 TERM 环境变量的情况下,可以使用 echoti colorsterminfo(5) 数据库中找到终端支持的最大颜色数。 对于 24 位颜色,还要使用 print $COLORTERM 检查 COLORTERM 环境变量。 如果它返回 24bittruecolor,则即使 terminfo 显示的数字较小,您的终端也支持 16777216 (224) 种颜色。

注意
  • 颜色 0–15 在不同的终端模拟器及其使用的配色方案之间可能有所不同。
  • 许多终端模拟器以更亮的颜色显示粗体。
提示
  • 提示符转义符可以使用命令 print -P "提示符转义符" 进行测试,例如
    $ 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 %~ %# '

显示效果

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 范围内的颜色和 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 文件

有关更多信息,请参阅 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'

记住最近的目录

目录堆栈

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,则由于两个会话都写入同一个文件时发生冲突,这将不起作用。
  • 您可能需要创建 $HOME/.cache/zsh 目录,以避免出现 no such file or directory 错误。

cdr

cdr 允许您从自动维护的列表中将工作目录更改为以前的工作目录。 它将所有条目存储在跨会话维护的文件中,并且(默认情况下)在当前会话中的终端模拟器之间维护。

有关设置说明,请参阅 zshcontrib(1) § REMEMBERING RECENT DIRECTORIES

zoxide

zoxide 是一个更智能的 cd 命令,可让您通过几次击键导航到任何地方。 它会记住您常用的目录,并使用评分机制来猜测您想去哪里。

帮助命令

Bash 不同,Zsh 不启用内置的 help 命令,而是提供 run-help。 默认情况下,run-helpman 的别名,可以通过在其前面加上命令手动执行,也可以使用键盘快捷键 Alt+hEsc 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 页面 git-commit(1) 而不是 git(1)

持久重哈希

通常,compinit 不会自动在 $PATH 中查找新的可执行文件。 例如,在安装新软件包后,/usr/bin/ 中的文件不会立即或自动包含在补全中。 因此,要包含这些新的可执行文件,需要运行

$ rehash

可以将此“重哈希”设置为自动发生。[3] 只需在您的 zshrc 中包含以下内容

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

按需重哈希

如上所述,但是 pacman 可以使用 hooks 进行配置,以自动请求 rehash,这不会像上面的常量重哈希那样产生性能损失。 要启用此功能,请创建 /etc/pacman.d/hooks 目录和 /var/cache/zsh 目录,然后创建一个 hook 文件

/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 在其自己的命令缓存过时时重新哈希它

~/.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 实例(包括登录 shell)如果尚未加载下面的 trap,都将终止。
~/.zshrc
TRAPUSR1() { rehash }

上面的函数 trap 可以用列表 trap trap 'rehash' USR1 替换。有关 trap 类型之间差异,请参阅 zshmisc(1) § Trap 函数

此方法将立即 rehash 所有 zsh 实例,无需按回车键来触发 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

拥有动态标题的一个简单方法是在 precmdpreexec 钩子函数中设置标题。有关可用钩子函数及其描述的列表,请参阅 zshmisc(1) § 钩子函数

通过使用 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_MODULEzshtcpsys(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 的文件数据库与正常的同步数据库是分开的,需要使用 pacman -Fy 获取。有关详细信息,请参阅 pacman#搜索包含特定文件的软件包

有关使用 pkgfile 的替代方案,请参阅 #pkgfile "command not found" 处理程序

使用快捷键清除回滚缓冲区

默认情况下,清除屏幕快捷键不会清除大多数终端模拟器上的回滚缓冲区(您需要向上滚动才能看到的部分)。以下是解决此问题的一种可能方案。

~/.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 — Antibody 插件管理器的功能完整的 Zsh 实现。
https://github.com/mattmc3/antidote || zsh-antidoteAUR
  • zinit (以前的 "zplugin") — 灵活的 Zsh 插件管理器,具有干净的 fpath、报告、补全管理、涡轮模式 已恢复
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。 已废弃
https://github.com/zsh-users/antigen || antigen-gitAUR
  • zgen — 一个轻量级且简单的 Zsh 插件管理器。 已废弃
https://github.com/tarjoilija/zgen || zgen-gitAUR
  • zplug — 下一代 Zsh 插件管理器。 已废弃
https://github.com/zplug/zplug || zplugAUR

类 Fish 的语法高亮和自动建议

Fish 提供了非常强大的 shell 语法高亮和自动建议。要在 Zsh 中同时使用两者,您可以安装 zsh-syntax-highlightingzsh-autosuggestions,最后 source 从您的 zshrc 中加载一个或两个提供的脚本

~/.zshrc
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 包含一个 Zsh 脚本文件,该文件提供了一个 command_not_found_handler 函数,该函数将在输入无法识别的命令时自动搜索 pkgfile 数据库。

您需要 source 该脚本以启用它。例如

~/.zshrc
source /usr/share/doc/pkgfile/command-not-found.zsh
注意: pkgfile 数据库可能需要更新后才能工作。有关详细信息,请参阅 pkgfile#安装

有关使用 pacman 原生功能的替代方案,请参阅 #pacman -F "command not found" 处理程序

另请参阅