win10安装wsl2并配置桌面环境

检测系统内核版本

要在Windows 10上安装WSL 2,需要以下东西:

  • Windows 10 2020年5月(2004)版, Windows 10 2019年5月(1903)版,或者Windows 10 2019年11月(1909)版
  • 一台支持Hyper-V虚拟化的计算机

如果不支持,请更新内核。下载更新需要的系统iso文件,挂载并运行即可(推荐使用win10_ltsc2021)。

启用WSL2支持

在「设置 -> 更新与安全->开发者选项」中开启「开发人员模式」
在「控制面板 -> 程序和功能 -> 启用或关闭 Windows 功能」中勾选「适用于Linux 的 Windows 子系统」和「虚拟机平台」
最后重启电脑

下载软件

下载Linux内核更新包

双击运行安装,powershell运行:
wsl --set-default-version 2

下载WSL发行版

选择Ubuntu_20.04,下载得到Ubuntu2004.AppxBundle,用PowerShell运行:<br> `Add-AppxPackage Ubuntu2004.AppxBundle`

下载VcXsrv

安装後打开XLaunch,可选择"One large window""Fullscreen""Multiple windows""Display number"设置成0,下一步选择"start no client",下一步勾选"Disable access control"(此页全勾选),下一步点击"save configuration"保存配置文件,以供之後连接wsl的桌面环境。

如果要进入完整的桌面环境,使用"One large window""Fullscreen",推荐使用前者,如果只是打开桌面应用,推荐使用"Multiple windows",这样linux应用和win应用在同一个win桌面显示,能提供无缝体验,但是有可能无法使用。

配置Ubuntu基础环境

打开wsl终端(开始菜单上的应用),首先进行换源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
sudo cp /etc/apt/sources.list /etc/apt/sources.list_backup
sudo vi /etc/apt/sources.list

#### 在文件开头添加以下内容:

# 默认注释了源码仓库,如有需要可自行取消注释
deb https://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse
# deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse

deb https://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse
# deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse

deb https://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
# deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse

deb https://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
# deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse

# 预发布软件源,不建议启用
# deb https://mirrors.ustc.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse
# deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse

按i键进入编辑模式,修改后,按ESC键退出编辑模式,输入":wq"保存并退出。然後,更新源并升级软件包: sudo apt update && sudo apt upgrade -y

配置Linux桌面环境

注意,linux桌面环境在wsl下可能都有一个问题:Alt+Tab之类的快捷键无法使用,这可能是因为与win10相冲突,可选择使用Ctrl+Alt+D(切换桌面)代替。

设置bashrc

1
2
3
4
5
6
7
8
sudo vi ~/.bashrc

#### 在文件末尾添加:
export DISPLAY=$(grep -m 1 nameserver /etc/resolv.conf | awk '{print $2}'):0.0
export XDG_SESSION_TYPE=x11

#### 然後执行:
source ~/.bashrc

启用systemd

这是废弃的方法:

1
2
3
git clone https://github.com/DamionGans/ubuntu-wsl2-systemd-script.git
cd ubuntu-wsl2-systemd-script/
bash ubuntu-wsl2-systemd-script.sh

或者(建议使用此方法):MicrosoftDocs/WSL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
sudo apt install -y fontconfig daemonize
sudo vi /etc/profile

#### 在文件末尾添加:
SYSTEMD_PID=$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')

if [ -z "$SYSTEMD_PID" ]; then
sudo /usr/bin/daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target
SYSTEMD_PID=$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')
fi

if [ -n "$SYSTEMD_PID" ] && [ "$SYSTEMD_PID" != "1" ]; then
exec sudo /usr/bin/nsenter -t $SYSTEMD_PID -a su - $LOGNAME
fi

sudo vi /etc/sudoers
#### 在文件末尾添加:
%sudo ALL=(ALL) NOPASSWD: /usr/sbin/daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target
%sudo ALL=(ALL) NOPASSWD: /usr/bin/nsenter -t [0-9]* -a su - [a-zA-Z0-9]*

重启 profile 文件使上面的配置生效:
sudo -s
source /etc/profile

或者直接运行写好的代码,以完成bashrc和systemd的配置:
桌面预配置
bash .code/ubuntu-wsl2-config-desktop.sh

桌面环境安装

安装xfce4桌面环境:sudo apt install xfce4
启动xfce4桌面环境:startxfce4&

安装lxqt桌面环境:sudo apt install lxqt openbox
启动lxqt桌面环境:startlxqt&
注意,lxqt安装後,Ctrl+Alt+T(启用终端快捷键)无效,请手动设置快捷键。

安装中文输入法

这里使用fcitx输入法,因为Ubuntu对fcitx5的支持不好。
首先安装软件包命令如下:
sudo apt install fcitx im-config dbus-x11 fcitx-frontend-all fcitx-libpinyin fcitx-sunpinyin fcitx-table-wubi
其中,fcitx包含了fcitx-frontend-all,im-config用以切换输入法,dbus-x11是必须的(否则无法切出输入法)。

然後,修改/etc/locale.gen文件,命令如下: printf "\nzh_CN.UTF-8 UTF-8" | sudo tee -a /etc/locale.gen

运行命令:sudo locale-gen

修改~/.bashrc文件,末尾添加如下内容(这一步也是必须的):

1
2
3
4
5
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export DefaultIMModule=fcitx
fcitx-autostart > /dev/null 2>&1 &

重启wsl再进入桌面环境配置fcitx输入法即可,启用中文键盘,注意要避免和win10冲突。

注意:请将win10键盘修改为English(美国),以免在wsl中的输入按键异常(方向键变成长按数字键2468)。

在Windows的「设置 -> 设备 -> 输入 -> 高级键盘设置」里面的切换输入法中,勾选允许我为每个应用窗口使用不同的输入法,以方便输入法切换。

WSL常用命令

  • wsl
    启用Linux shell
  • wsl --help
    显示用法信息
  • wsl <--exec|-e> <命令行>
    在不使用默认Linux Shell的情况下执行指定的命令
  • wsl -- <命令行>
    按原样传递其余命令行
  • wsl <--distribution|-d> <分发>
    运行指定发行版
  • wsl --update
    手动更新WSL Linux内核的版本
  • wsl --status
    查看有关WSL配置的常规信息
  • wsl <--set-default|-s> <分发>
    将分发设置为默认值
  • wsl --set-version <分发> <版本>
    更改指定分发的版本
  • wsl --import <分发> <安装位置> <文件名>
    导入指定的tar文件作为新的分发版
  • wsl --export <分发> <导出文件>
    将分发版导出到tar文件
  • wsl <--terminate|-t> <分发>
    终止指定的分发
  • wsl --shutdown
    立即终止所有运行的分发及WSL轻型工具虚拟机
  • wsl --unregister <分发>
    注销分发并删除根文件系统
  • wsl <--list|-l> <--verbose|-v>
    列出所有分发的名称、运行状态、对应的WSL版本

WSL关于PATH的问题

在wsl中,Linux的PATH变量自动加上Windows中的PATH部分,以便互操作。

但是,wsl启动不会加载"/etc/environment"文件,好像也不会自动加载"/etc/profile"文件,因此对PATH的这些更改都不会生效

推荐的解决方法是更改bashrc文件,如果是用户登录bash,则更改"~/.profile"或者"~/.bashrc"文件。

wsl启动时,会加载"/etc/bash.bashrc"文件,总之,启动流程和通常的Linux不一样。

如果要在系统的PATH中添加路径,请在Windows里面设置环境变量并重启LxssManager服务:

net stop LxssManager
net start LxssManager

或者,可以关闭wsl的自动加载Windows环境变量这一特性(不知道是否有效)。

wsl-terminal的使用

最好不要使用默认的像cmd那样的wsl终端,因为用起来很不方便。

我更为推荐使用微软提供的WindowsTerminal工具,功能足够强大。

基于mintty的wsl终端

可以用msys2的终端mintty通过ssh连接wsl里面的Linux发行版。

也可以用mintty配合wslbridge完成wsl的连接,这里使用的就是这种。

下载github上的wsl-terminal, 直接解压到某一个目录下,有几个exe文件:

  1. open-wsl.exe 打开默认的wsl发行版
  2. run-wsl-file.exe 运行wsl里面的可执行文件
  3. vim.exe 打开wsl里面对应的程序,通过将vim.exe重命名为emacs.exe可以执行wsl里面的emacs,其他亦可

详细的使用方法可以参考此项目的github.

程序目录下的tools文件夹下有一些方便的脚本:

  • 1-add-open-wsl-terminal-here-menu.js
    添加Open wsl-terminal Here上下文菜单项到文件浏览器中
  • 2-add-wsl-terminal-dir-to-path.js
    添加wsl-terminal的程序目录到Path环境变量
  • 3-write-distro-to-config-file.js
    将wsl发行版的guid写入到etc/wsl-terminal.conf
  • 4-create-start-menu-shortcut.js
    创建快捷执行open-wsl -C ~的开始菜单快捷方式
  • 4-create-start-menu-shortcut-login-shell.js
    创建快捷执行open-wsl -l的开始菜单快捷方式
  • 5-add-open-with-vim-menu.js
    添加Open with vim in wsl-terminal上下文菜单项到文件浏览器中
  • 6-set-default-shell.bat
    设置默认的wsl的shell环境为etc/wsl-terminal.conf配置的shell

同样有一些用于移除这些设置的脚本,这里不列出。
注意,可以在windows命令行中直接以路径运行这些脚本。

关于右键菜单以vim方式打开的bug:

如果打开的是含中文路径的文件,则会出闪退,打开含空格路径也会出问题,具体表现为文件路径被空格分割为几个字符串,而vim打开的是这些字符串所代表的文件。

解决方案:

  1. 复制vim.exe到同目录并改名为wslterm.exe

  2. 程序目录下新建nvim.bat文件,内容为:

     @echo off
     chcp 65001
     echo "%~1" > D:\wsl.cache
     %~d0
     cd "%~dp0"
     wslterm.exe "%~dp1%~n0"
  3. 同样新建wslterm文件,内容为:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #!/bin/bash

    source ~/.bashrc

    # 更改IFS是必要的
    IFS_OLD=$IFS
    IFS=$'\t'

    # 读入文件内容到变量,并去掉回车符,将换行符变为制表符,以便参数解析
    para=(`cat /mnt/d/wsl.cache | sed 's/\r//g' | sed ':j;N;s/\n/\t/g;b j'`)

    # 反斜杠替换
    para[0]=${para[0]//\\/\/}

    if [ ${para[0]} ]; then
    if [[ $(expr index ${para[0]} :) -ne 0 ]]; then
    if [[ $(expr index ${para[0]} :) -eq 3 ]]; then
    # 驱动器号变小写
    patr=$(echo -n ${para[0]:1:1} | sed 's/[A-Z]/\l&/g')
    # 驱动器前缀变为正确的wsl路径
    para[0]=${para[0]/${para[0]:1:2}/\/mnt\/$patr}
    else
    echo "the ':' is not a correct position!"
    exit
    fi
    fi
    else
    IFS=$IFS_OLD
    ${1##*\/}
    exit
    fi
    # 恢复IFS字符
    IFS=$IFS_OLD

    # 删除临时文件
    rm /mnt/d/wsl.cache

    echo "调用参数是:"
    echo -n ${para[@]}
    echo "调用参数结束."
    # 调用参数
    echo -n ${para[@]} | xargs ${1##*\/}

    在wsl中将此文件复制到/usr/bin/路径下并添加可执行权限。

  4. 5-add-open-with-vim-menu.js的基础上创建fix-add-open-with-nvim-menu.js文件,只需要修改文件内容即可:将最后一个vim.exe替换为nvim.bat.

  5. 可以创建相应的fix-remove-open-with-nvim-menu.js脚本以方便移除上述的功能。

微软官方WindowsTerminal

由于我的win10系统是企业版,没有应用商店,因此无法使用应用商店安装这些软件。

我的解决方法是使用winget进行软件包的安装和管理,但是winget的安装也比较麻烦。

winget的安装

借由winget进行软件包安装是比较好的方法,先安装winget,在github上的winget-cli下载对应的安装包即可。

在PowerShell中使用Add-AppPackage package-name命令来安装。

安装后仍不能使用winget(这应该是个小bug),需再次双击此安装包触发winget的初始化。

可能会出现问题,提示缺少Microsoft.VCLibsMicrosoft.UI.Xaml,需要去github上的WindowsTerminal下载Win11PreinstallKit版本的压缩包,解压到新目录,里面有这两个安装包,安装对应 处理器架构的即可。

注意:请检查你的系统是否缺少上述两个依赖,避免重复安装。
winget可以使用你设置的系统代理来访问网络,由于某些资源被墙,请自行使用代理。

WindowsTerminal也可以这样安装,其安装包是上述解压的一个msixbundle文件,其文件名是32个字母或数字的uuid,但是我不推荐这样安装,注意win10系统使用win11的安装包。

确保你能在windows的终端(例如powershell)运行:winget --help
此命令列出了使用winget的方式。

WindowsTerminal的安装

可以使用Add-AppxPackage或者应用商店安装,也可以使用winget安装:

winget install --id=Microsoft.WindowsTerminal -e

或者安装预览版的WindowsTerminal,命令如下:

winget install --id=Microsoft.WindowsTerminal..Preview -e
使用教程

WindowsTerminal使用起来还是非常简单,只是有些设置需要更改,推荐结合快捷键使用。

快捷键使用

通常WindowsTerminal可以直接使用,为了方便,首先是快捷键:

  • <C-[a-z]>: Ctrl开头的组合键
  • <A-[a-z]>: Alt开头的组合键
  • <S-[a-z]>: Shift开头的组合键,代替输入大写字母键
快捷键 操作
<A-CR> 切换全屏
<C-S-p> 切换命令面板
<C-Tab> 下一个标签页
<C-S-Tab> 上一个标签页
<C-A-[1-7] 切换到第几个标签页
<C-S-t> 新建默认标签页
<C-S-[1-9]> 新建第几个预设的标签页
<A-S-w> 关闭当前标签页,需手动添加
<C-S-w> 关闭窗格
<A-S> =<A-S> - 垂直/水平拆分窗格
<A-S-[1-8]> 移动当前窗格至第几个标签页,需手动添加
<A-S> 方向键 调整当前窗格大小,优先移动窗格底部和右边的线
Alt 方向键 光标在窗格中切换
<C-S-PgUp/PgDown> 向上/向下滚动一页
<C-S-Up/Down> 向上/向下滚动
<C-S-Home/End> 滚动至历史记录顶部/底部
Ctrl +/=/- 增加或减少字号
<C-0> 重置字号
<C-S-c><C-Ins> 复制文本,也可以用<C-c>
<C-S-v><S-Ins> 粘贴文本,也可以用<C-v>或者鼠标右键
<C-S-s> 查找缓冲区,默认的快捷键冲突而更改为此
<C-S-n> 新建WindowsTerminal窗口
更改设置

以下详述WindowsTerminal中我更改的各种设置:

「启动」页面,设置默认配置文件为你常用的wsl发行版,勾选「在计算机启动时启动」,「在终端启动时」设置为「打开来自上一个绘画的窗口」,「启动大小」更改为合适值。

「外观」页面,开启「在选项卡行中使用亚克力材料」。

「操作」页面,新增在"快捷键使用"中需要手动添加的快捷键,删除<C-c><C-v>快捷键以免wsl发行版中不能用<C-c>发送SIGINT信号。

「默认值 -> 外观」页面,更改字体和字号为合适值,光标形状更改为空心框,强调文本样式为亮色加粗字体,背景100%不透明且启用亚克力材料,窗口边框边距改为0且滚动条可见性设为隐藏。

「默认值 -> 高级」页面,文本抗锯齿设置为ClearType,历史记录大小设置为20000.

「配置文件」页面,所有wsl的配置页面中,「命令行」中的wsl.exe后面加一个参数~,这是为了避免一个问题

问题解决

关于WindowsTerminal的bug:
在某些版本的win系统上,可能出现wsl发行版无法启动的bug,表现如下:

The system cannot find the file specified.
[process exited with code 4294967295 (0xffffffff)]

解决方案:
目前无解,详见WSL问题WindowsTerminal问题

这个问题只能避免之,即不要在wsl发行版的配置文件的「启动目录」中使用win路径,或者在「命令行」中设置启动目录参数以忽略导致异常的「启动目录」设置。

添加类似文件拖曳的功能:

需要注意,WindowsTerminal目前是不支持通过拖曳文件到其窗口从而快捷输入文件路径,而PowerShell和cmd都是支持这一功能的,我的解决方案是"曲线救国"的方式。

在Windows文件浏览器中,快捷复制文件路径的方法:

  1. 选中一个或多个文件或目录,按住Shift并鼠标右键,弹出菜单中可以复制为路径。
  2. 选中文件后,「主页」菜单有「复制路径」的按钮,点击即可。

我不更改WindowsTerminal的任何地方,也不借由其实现所需功能,我注意到Windows的文件浏览器是可以将文件路径快捷复制到系统剪切板的,于是可以利用剪切板进行交互以实现我所需的功能,具体步骤如下:

  1. 在Windows文件浏览器中,「主页」菜单的「复制路径」按钮上鼠标右键并点击"添加到快速访问工具栏",然后复制路径可以快速完成。

  2. 在wsl发行版中安装xclip,命令为sudo apt install xclip.

  3. 在wsl发行版中,新建clippath并编辑:sudo vim /usr/bin/clippath

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #!/bin/bash

    # 这个文件是为了将剪切板的windows路径转换为wsl路径并输出
    # source ~/.bashrc

    # 更改IFS是必要的
    IFS_OLD=$IFS
    IFS=$'\t'

    # 读入剪切板内容到变量,并去掉回车符和双引号,将换行符变为制表符,以便参数解析
    para=(`xclip -sel clip -o | sed 's/"//g' | sed 's/\r//g' | sed ':j;N;s/\n/\t/g;b j'`)

    if [ ${para[0]} ]; then
    len=${#para[@]}
    for ((i=0;i<len;i++)); do
    # 反斜杠替换
    para[$i]=${para[$i]//\\/\/}
    # 加上双引号
    para[$i]="\"${para[$i]}\""
    if [ ${para[$i]} ]; then
    if [[ $(expr index ${para[$i]} :) -ne 0 ]]; then
    if [[ $(expr index ${para[$i]} :) -eq 3 ]]; then
    # 驱动器号变小写
    patr=$(echo -n ${para[$i]:1:1} | sed 's/[A-Z]/\l&/g')
    # 驱动器前缀变为正确的wsl路径
    para[$i]=${para[$i]/${para[$i]:1:2}/\/mnt\/$patr}
    else
    echo "the ':' is not a correct position!" >&2
    exit
    fi
    fi
    fi
    done
    fi

    # 恢复IFS字符
    IFS=$IFS_OLD

    # 调用参数
    echo -n ${para[@]}
  4. ~/.bash_aliases文件中增加别名设置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function echo_to_directory ()
    {
    # 如果是目录则输出,是文件则输出其目录
    if [ -d "$*" ]; then
    echo -n "\"$*\""
    else
    echo -n "\"$(dirname "$*")\""
    fi
    }
    alias cdp='eval cd "$(eval echo_to_directory `clippath`)"'
    alias cl='clippath'
    alias evim='eval nvim'
  5. 执行source ~/.bashrc命令以应用bash设置。

具体操作有:

  • 切换到剪切版中的Windows目录:
    首先在Windows文件浏览器中选择文件或目录,复制路径到剪切板,然后在wsl终端中执行cdp即可切换工作目录到复制路径的目录部分。
  • 用nvim打开剪切板中的多个路径的文件:
    注意,执行cl命令会在一行中输出剪切板中的多个文件路径,根据上述配置的,可以执行 evim `cl` 来用nvim打开剪切板中路径的文件。
    执行 vi `cl` 可以在qterminal中的nvim打开这些文件。

注意,vi命令是在我写的"SpaceVim使用教程"中提到的别名(alias)。
可以看到,这基本满足了我们对文件拖曳功能的需求,只是使用方式有点不一样。


win10安装wsl2并配置桌面环境
https://blog.siantao.top/实践/计算机/软件/WSL/win10安装wsl2并配置桌面环境/
作者
玉水仙楊
发布于
2022年5月1日
许可协议