配置 zsh 作为日常使用的终端 shell
linux
linux 下配置 zsh 比较简单, 基本上都能用包管理器和 git 进行安装
安装 zsh
直接使用命令行就能安装 zsh
-
ubuntu:
sudo apt install zsh -
arch
# 使用pacman sudo pacman -S zsh # 使用yay或者paru yay/paru -S zsh
配置 zsh 为当前用户默认 shell
查看当前 shell:
echo $SHELL
# 一般结果都是/bin/bash
设置 zsh 为当前用户默认 shell:
sudo chsh $USER
# 输入zsh的位置, 一般使用/bin/zsh
安装 oh-my-zsh
oh-my-zsh 官网提供两种方式进行简单安装
# 通过curl
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
# 通过wget
sh -c "$(wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)"
或者使用 github 镜像
# 使用curl
sh -c "$(curl -fsSL https://gh-proxy.com/https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
# 使用wget
sh -c "$(wget -O- https://gh-proxy.com/https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
安装时会选择使用 omz 的.zshrc 替换原有的, 同时原来的.zshrc 会进行备份变成.zshrc.pre-oh-my-zsh
配置 zsh 插件
个人一般只用 zsh-syntax-highlighting 和 zsh-autosuggestions, 其他的就不做考虑
使用 git 将插件 clone 到本地 omz 插件目录
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
或者使用 github 镜像
git clone https://gh-proxy.com/https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
git clone https://gh-proxy.com/https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
在.zshrc 中启用插件, 找到这一行
plugins=(git)
添加插件
plugins=(git zsh-autosuggestions zsh-syntax-highlighting)
重新 source 一下就行
source .zshrc
配置 powerlevel10k
本来之前用的是 omz 不加主题, 搭配 starship, 但是有点繁琐了, 所以就直接拿 powerlevel10k 来用了
同样使用 git 把主题 clone 到本地 omz 目录
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k
或者使用 github 镜像
git clone --depth=1 https://gh-proxy.com/https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k
完成之后修改.zshrc
ZSH_THEME="powerlevel10k/powerlevel10k"
重新 source 一下.zshrc 就能看到 p10k 的引导界面, 根据引导进行设置即可
windows
window 之前用的 pwsh 加 starship, 也还行, 但是偶然想着能不能统一用 zsh
配置过程比 linux 要繁琐一点
安装 git
安装 git 没什么好说, 可以直接上官网下载
这里推荐找个国内镜像比如清华源, 在主页右边常用软件包安装程序中可以找到
唯一需要注意的是在安装时需要选择向 window terminal 添加 git-bash 的 profile
安装完成后把 git-bash 设置成默认 shell 的过程不多赘述
安装 zsh
git-bash 为 windows 提供了一个 bash 环境, zsh 需要额外安装
zsh 可以直接在 msys2 找到包

下载名为 zsh-$version$-x86_64.pkg.tar.zst 的包, 版本截至文章编写时为 5.9-4
两次解压后得到文件夹, 目录结构如下
|-- .BUILDINFO
|-- .INSTALL
|-- .MTREE
|-- .PKGINFO
|-- etc
| `-- zsh
`-- usr
|-- bin
|-- lib
`-- share
将整个文件夹覆盖到 git 安装目录, 再次打开 git-bash 即可调用 zsh
由于 git-bash 下没有 chsh 命令, 所以只能通过修改.zshrc 来让每次启动时自动切换到 zsh
在.bashrc 中加入如下内容(文件的末尾)
if [[ $- == *i* ]] && [ -t 1 ]; then
exec zsh
fi
安装并配置 oh-my-zsh
omz 在 git-bash 的环境下安装方式相同, 参照上面 linux 的安装方法即可
解决 conda 和 mamba 的 hook 问题
在 windows 上使用 bash 或 zsh 这类 shell 时, 不可避免会遇到换行符的问题
如果按照上面的内容安装完了 zsh 之后使用 conda 和 mamba 进行 init, 会出现 ^M 也就是回车导致 zsh 解析失败, powerlevel10k 的 instant prompt 功能失效
问题定位
在使用 conda 和 mamba 进行 zsh 的 init 后, .zshrc 中会添加两段 hook, 启用 conda 和 mamba 的对应功能
每次打开 zsh 会报错
[WARNING]: Console output during zsh initialization detected.
When using Powerlevel10k with instant prompt, console output during zsh
initialization may indicate issues.
You can:
- Recommended: Change ~/.zshrc so that it does not perform console I/O
after the instant prompt preamble. See the link below for details.
* You will not see this error message again.
* Zsh will start quickly and prompt will update smoothly.
- Suppress this warning either by running p10k configure or by manually
defining the following parameter:
typeset -g POWERLEVEL9K_INSTANT_PROMPT=quiet
* You will not see this error message again.
* Zsh will start quickly but prompt will jump down after initialization.
- Disable instant prompt either by running p10k configure or by manually
defining the following parameter:
typeset -g POWERLEVEL9K_INSTANT_PROMPT=off
* You will not see this error message again.
* Zsh will start slowly.
- Do nothing.
* You will see this error message every time you start zsh.
* Zsh will start quickly but prompt will jump down after initialization.
For details, see:
https://github.com/romkatv/powerlevel10k#instant-prompt
-- console output produced during zsh initialization follows --
omz 检测到了在 zsh 初始化时的输出, 在报错信息后紧接着两行
(eval):7: parse error near `^M'
(eval):15: parse error near `^M'
也就是脚本中包含了 windows 的回车, conda 和 mamba 的 init 过程失败, 导致 zsh 无法解析从而产生输出, 影响了 powerlevel10k 的 instant prompt 功能
回看.zshrc, 其中确实包含了两行 eval
# conda
eval "$('/d/miniforge3/Scripts/conda.exe' 'shell.zsh' 'hook')"
# mamba
eval "$("$MAMBA_EXE" shell hook --shell zsh --root-prefix "$MAMBA_ROOT_PREFIX")"
具体内容是 conda 和 mamba 各自调用了自己的 hook, 生成了自己的临时 hook 脚本, 交由 eval 来执行
但由于 conda 和 mamba 属于 windows 程序, 生成 hook 脚本过程中添加的换行符全部都为 windows 换行
eval 在执行 hook 脚本时无法解析其中的回车符(^M)从而发生了错误
上面的内容可以通过下面的方法来验证
# 手动执行命令生成hook脚本
'/d/miniforge3/Scripts/conda.exe' 'shell.zsh' 'hook' > conda_hook.txt
# 使用cat显示所有特殊字符
cat -A conda_hook.txt
回显中会包含大量 ^M
临时解决方案是在对应的命令结尾加上管道符将生成的 hook 脚本交由 dos2unix 来处理
使用 dos2unix 替换原来的 windows 换行为 unix 换行, 再交由 eval 来执行
# conda
eval "$('/d/miniforge3/Scripts/conda.exe' 'shell.zsh' 'hook' | dos2unix)"
# mamba
eval "$("$MAMBA_EXE" shell hook --shell zsh --root-prefix "$MAMBA_ROOT_PREFIX" | dos2unix)"
但是, 替换后仍然发生报错
(eval):unset:1: _CE_M^M: invalid parameter name
发现竟然还有 ^M?
于是对生成的 hook 脚本进行检查, 发现在 conda 的 hook 脚本中包含一个 eval
__conda_activate() {
if [ -n "${CONDA_PS1_BACKUP:+x}" ]; then
# Handle transition from shell activated with conda <= 4.3 to a subsequent activation
# after conda updated to >= 4.4. See issue #6173.
PS1="$CONDA_PS1_BACKUP"
\unset CONDA_PS1_BACKUP
fi
\local ask_conda
# 这里生成命令
ask_conda="$(PS1="${PS1:-}" __conda_exe shell.posix "$@")" || \return
# 这里eval执行
\eval "$ask_conda"
__conda_hashr
}
也就是说在 hook 脚本中又生成了一条临时命令交由 eval 来执行, 毫无疑问这里生成的内容包含 ^M
于是对 conda 的 hook 命令再做修改, 使用正则将 hook 脚本中对应的内容进行修改, 也就是加上 dos2unix
eval "$('/d/miniforge3/Scripts/conda.exe' 'shell.zsh' 'hook' \
| sed 's#__conda_exe shell\.posix "\$@"#__conda_exe shell.posix "$@" | dos2unix#' \
| dos2unix)"
原以为万事大吉, 结果依旧报错, 这回是 python
Traceback (most recent call last):
File "D:\miniforge3\Lib\site-packages\conda\exception_handler.py", line 28, in __call__
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "D:\miniforge3\Lib\site-packages\conda\cli\main.py", line 87, in main_sourced
print(activator.execute(), end="")
UnicodeEncodeError: 'gbk' codec can't encode character '\uf253' in position 937: illegal multibyte sequence
python 在执行 hook 时无法解析'uf253'(默认使用 gbk)
所以这里直接在.zshrc 环境变量添加一条
export PYTHONIOENCODING=utf-8
问题解决
最终方案
将 conda 和 mamba 的 hook 命令进行替换
# conda
eval "$('/d/miniforge3/Scripts/conda.exe' 'shell.zsh' 'hook')"
# conda(patch)
eval "$('/d/miniforge3/Scripts/conda.exe' 'shell.zsh' 'hook' \
| sed 's#__conda_exe shell\.posix "\$@"#__conda_exe shell.posix "$@" | dos2unix#' \
| dos2unix)"
# mamba
eval "$("$MAMBA_EXE" shell hook --shell zsh --root-prefix "$MAMBA_ROOT_PREFIX")"
# mamba(patch)
eval "$("$MAMBA_EXE" shell hook --shell zsh --root-prefix "$MAMBA_ROOT_PREFIX" | dos2unix)"
并添加一条环境变量(在.zshrc 的对应位置, conda 和 mamba 的 hook 执行之前)
export PYTHONIOENCODING=utf-8

欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于