Zsh (简体中文)
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
将 Zsh 设为默认 Shell 软件
将 Shell 改为 /usr/bin/zsh
。参见 更改你的 Shell 软件。
~/.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)。
/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 有 emacs 和 vi 两个模式,默认情况下它根据环境变量 $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 不同。 在 .zshrc
中 PROMPT=
前面添加 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 样例
- 官方仓库里来自 https://grml.org/zsh 的软件包 grml-zsh-config 中包含了很多 Zsh 的配置技巧
- https://github.com/MrElendig/dotfiles-alice/blob/master/.zshrc 包含一些动态提示符和终端窗口标题等基本配置
- https://github.com/slashbeast/conf-mgmt/blob/master/roles/home_files/files/DOTzshrc 拥有很多特性的 zsh 配置,注意阅读它的注释。值得注目的特性:关机、重启和睡眠的用户确认交互函数,命令提示符内支持 GIT(没有使用 vcsinfo),菜单使用 tab 补全,打印当前执行的命令到终端窗口的标题上,等等。
配置框架
- 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
卸载
在卸载 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
另请参见
- A User's Guide to ZSH
- The Z Shell Manual (different format available here)
- Zsh FAQ
- zsh-lovers(1) (this is also available as zsh-lovers in offical repository)
- Zsh Wiki
- Gentoo Wiki: Zsh/HOWTO
- Bash2Zsh Reference Card