# Shell 环境
🍌 本文内容
本文中我们将对 WSL 的 Shell 环境进行配置。这里面包括默认 bash
的配置,更用户友好的 zsh
、fish
的配置以及一些常见问题的解决办法等。
# 更换软件源镜像
为了加速 Ubuntu 软件包在中国大陆的下载速度,我们将包管理工具 apt
源更换至清华 TUNA 软件源镜像。Ubuntu 的软件源配置文件是 /etc/apt/sources.list
。将系统自带的该文件做个备份,将该文件替换为下面内容,即可使用 TUNA 的软件源镜像。
备份原文件:
$ sudo cp /etc/apt/sources.list /etc/apt/sources.list.bac
在配置文件
/etc/apt/sources.list
最前面添加下面的内容(下面内容为默认 Ubuntu 20.04 LTS 版本的内容):# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释 deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse # 预发布软件源,不建议启用 # deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse
更新缓存:
$ sudo apt update && sudo apt upgrade
更多内容请参考:Ubuntu 镜像使用帮助 - 清华大学开源软件镜像站
# APT
APT - Debian's Advanced Packaging Tool 是 Ubuntu 默认包管理工具,它是由 Debian 社区开发的。使用 Ubuntu 等基于 Debian 的 Linux 发行版时,我们往往都会使用 APT 等相似的包管理工具来安装、更新我们的软件包。命令 apt
和 apt-get
与 APT 不同,它们是用来和 APT 进行交互的高层命令执行工具。请大家清楚二者的区别。
其中,在 Ubuntu 16.04 中 Ubuntu 引入了 apt
命令来代替曾经老用户熟悉的 apt-get
,提供了更用户友好的操作和命令行界面,对软件包 cache 缓存的处理也更为优雅。这里我推荐大家使用 apt
命令来与 APT 包管理工具交互,安装、管理和更新软件和依赖,接下来的文档中,我也都会使用 apt
命令进行介绍。
推荐阅读:Difference Between apt and apt-get Explained - It's FOSS
# bash
下载安装的 Windows Subsystem for Linux 默认就是 bash
的 Shell 环境。bash
是 Unix shell 的一种,是我们开发环境的基础。不过 bash
本身仅提供一个非常基础的命令行交互功能,没有类似 zsh
或 fish
等 Shell 的自动补全、命令提示等高阶功能。因此,这里推荐大家继续阅读,安装 zsh
或 fish
来替代 bash
。
zsh
和 fish
,都是 Unix-like 系统中不可或缺的好 Shell,它们都极大的拓展了我们命令行界面的交互体验。在命令行的世界中:
fish
更加注重「开箱即用」的体验,让我们安装完成即拥有一个包含了命令高亮、自动补全等强大功能的 Shell 环境zsh
则更加重视拓展性,借助于社区中优秀的zsh
插件系统 oh-my-zsh 以及无数优秀的插件,zsh
同样能有比肩fish
甚至比fish
更高阶的功能和体验
同学们可以根据自己实际情况,在这两个 Shell 中二选一即可。在之后的文档中,我会用 zsh 作为默认的 Shell 进行介绍。
# zsh
# 安装、配置
安装 zsh
并将之设置为默认 Shell:
利用 apt 安装
zsh
$ sudo apt install zsh
下载安装 oh-my-zsh,可能是市面上最好的 zsh
配置管理工具:
运行命令下载安装
$ sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
将
zsh
作为默认的 Shell 环境(如果刚刚安装脚本没有这样做的话):$ chsh -s $(which zsh)
# 插件、主题模板推荐
zsh
拥有相当丰富的主题、插件等拓展内容,这里我仅列举一些我常用的配置插件和主题模板:
# 插件
- zsh-autosuggestions:为
zsh
提供基于输入历史的自动命令提示 - autojump:快速跳转不同的目录、路径、文件夹
- zsh-syntax-highlighting:为
zsh
命令提供色彩高亮
# 主题模板
- starship - The cross-shell prompt for astronauts
- powerlevel10k - A fast reimplementation of Powerlevel9k ZSH theme
主题模板和插件的安装在它们各自的文档中都有详细的介绍,这里不再赘述。
# fish
开箱即用的 fish
无需安装以上 zsh
中繁琐的插件就能拥有几乎全部上面提到的功能。如果你觉得 zsh
的配置繁琐无趣,那么 fish
可能更符合你的口味。
# 安装 fish
同样使用 Ubuntu 中的包管理工具安装 fish
:
$ sudo apt install fish
将 fish
作为默认 Shell:
$ chsh -s $(which fish)
# 配置
未经任何配置的 fish
即直接支持了诸多优秀的命令行交互特性。上图的例子中,我们可以看到 fish
开箱自带的几个功能:
- 输入命令的实时高亮,错误命令标红
- 历史命令的记忆,对输入命令的实时补全
- 对
*.png
等通配符(Wildcard character)的支持 - 相对 decent 的命令提示符(Prompt)
fish
的配置文件位于 ~/.config/fish/config.fish
,这一文件之于 fish
就像 .zshrc
之于 zsh
、.bashrc
之于 bash
一样。
有关 fish
的配置方法推荐大家查看其官方文档:fish tutorial - fish shell
# 常见问题
# 解决字符渲染问题
由于 Windows 下的终端们,除了微软自己开发的 Windows Terminal 外,都尚未很好的支持全角(Double width)的 Unicode 字体渲染,因此 oh-my-zsh 默认主题 robbyrussell 在某些终端(比如 Hyper)下会出现光标位置不正确的问题(见 Issue #5)。目前有这样的几种解决方法:
# 使用 Windows Terminal
最方便、理智、没有妥协的方法:使用 Windows Terminal。🤣
最新的 Windows Terminal 在底层修改了字符的渲染方式,采取最新的渲染引擎,拥有最好的性能和最美的 UI,能够支持几乎全部字符的渲染(甚至包括 Emoji),我认为没有不选择直接使用 Windows Terminal 的理由。
如果你一定要使用非 Windows Terminal 的终端来进入 WSL 的话,下面两个方法可能可以解决你的问题。
# 修改终端显示内容
对 oh-my-zsh 默认主题文件 robbyrussell 来说:
- 在
~/.oh-my-zsh/themes
目录下打开 oh-my-zsh 默认主题文件:robbyrussell.zsh-theme
,将其中的全角 Unicode 字符「➜」更改为其他字符(比如「>」或者「→」) - 加载设置:
source ~/.zshrc
需要注意的是,很多 oh-my-zsh
主题(包括 更加酷炫的 Powerlevel10k
主题包)都用到了上文提到的 Powerline Fonts 和 Nerd Fonts,而这些字形在 Windows 任何终端下都没有很好的支持,因此目前一个很好的解决方法是:
- 将酷炫的命令前部分放在一行单独显示
- 将需要输入的带有光标的命令部分放在第二行显示
比如:如果你使用了 Powerlevel10k 主题包,可以考虑将下面的内容加入 .zshrc
来实现命令单独在第二行的显示:
# 让命令主体单独在第二行显示
POWERLEVEL9K_PROMPT_ON_NEWLINE=true
# 让右侧命令不显示(右侧命令同样无法正常在 Windows 下渲染)
POWERLEVEL9K_DISABLE_RPROMPT=true
# 上文截图中的两行命令前部字符的配置
POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX="╭"
POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX="╰\u276F\u276F\u276F "
这样配置之后,终端中的光标位置就不会出现错位问题了,同时也不影响终端的炫酷和易用。🍻
# 修改 Windows 终端为 UTF-8 环境
Windows 终端输出错位、光标错位的根本原因在于 Windows 终端默认并非是 UTF-8 的环境(至少中文默认环境下不是)。我们可以通过下面的方法保证 Windows 终端环境为 UTF-8 的编码方式:
- 首先,在「控制面板 → 区域」,选择「非 Unicode 程序语言设置」,更改为「英语」,并勾选下方「Beta:使用 Unicode UTF-8 支持全球语言」的选项
- 之后,在 PowerShell 终端中输入
chcp 65001
,切换为 UTF-8 代码页
理论上,你就可以成功将 Windows 全部终端环境切换为 UTF-8 的编码格式了。也就是说,就算是在 Fluent Terminal 中显示下面带有左右 Prompt 的 Powerlevel9k 配置,你的终端显示都是正确无误的,光标位置也是符合预期的。
但是这种方法比较玄学,因此如果你并没有成功解决问题,还请使用第一种办法。与此同时,这种方法也可能对中文环境下的一些程序造成显示乱码的问题,就我遇到的问题来说:TIM(QQ 办公简洁版客户端)的输入框显示字体从微软雅黑变成了中易宋体,另外一些个人开发者的应用程序(比如酷安 @晨钟酱 开发的多亲 AI 工具箱)完全乱码。请大家谨慎操作。
# 解决 ls
命令背景色问题
🔋 贡献
感谢 @printempw 提供的从根源解决这个问题的方式。由于 DrvFs 文件权限问题导致出现有问题的背景色根本原因在于这里:DrvFs 文件权限问题。
可以发现,上面我们在 Linux 自己的文件系统中时,ls
命令的输出没什么问题,但是当我们在 WSL 中进入 Windows 文件系统中时,ls
命令输出则变成了白底绿色背景。简单来说,这是由于 DrvFs 文件系统的权限问题,导致 Windows 原有 NTFS 文件系统中的文件到 WSL 下权限全部变成 0777。这样在 WSL 中执行 ls
和 cd
命令之后,显示出来的结果背景色就会出现「问题」。(不过,事实上这是有意而为之的。)
# 如果不想对文件系统的权限进行修改
可以在
.zshrc
最尾部添加如下代码# Change ls colours LS_COLORS="ow=01;36;40" && export LS_COLORS # make cd use the ls colours zstyle ':completion:*' list-colors "${(@s.:.)LS_COLORS}" autoload -Uz compinit compinit
加载设置:
source ~/.zshrc
# 如果希望从根本上解决 DrvFs 文件系统的权限问题
以下内容来自 @printempw 提供的这篇文章 > DrvFs 文件权限问题。
在 WSL 中创建
/etc/wsl.conf
,在其中填写如下内容:[automount] enabled = true root = /mnt/ options = "metadata,umask=22,fmask=111" mountFsTab = true
重启 WSL,所有的盘符就会使用上面的配置自动挂载(可以使用
mount -l
查看)
🔁 重启 WSL 环境
我们在退出所有开启 WSL 的终端 session 后,可以在 Windows 侧(比如 PowerShell 中)使用命令 wsl -t <Distro Name>
来关闭 WSL 环境。其中,WSL 发行版的名字可以用命令 wsl -l
列出,比如:你安装的是 Ubuntu,那么在运行 wsl -t Ubuntu
后再打开 WSL,就能观察到重新挂载盘符了。
另外,如果你想要给不同的盘符设定不同的挂载参数(上面的方法对所有盘符都有效,如果你想在 WSL 中运行 Windows 下的应用程序,就得每次都 chmod +x
一下,所以我一般都会把 C: 排除掉),就需要手动修改 /etc/fstab
。首先确保 wsl.conf
中的 mountFsTab
为 true
,然后编辑 /etc/fstab
,添加如下内容:
# 不在此列表中的盘符会使用 wsl.conf 中的参数挂载
# 格式可以自己去查 fstab 的帮助文档
E: /mnt/e drvfs rw,relatime,uid=1000,gid=1000,metadata,umask=22,fmask=111 0 0
← 终端 Terminal 命令行工具 →