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 | |
按i键进入编辑模式,修改后,按ESC键退出编辑模式,输入":wq"保存并退出。然後,更新源并升级软件包:
sudo apt update && sudo apt upgrade -y
配置Linux桌面环境
注意,linux桌面环境在wsl下可能都有一个问题:Alt+Tab之类的快捷键无法使用,这可能是因为与win10相冲突,可选择使用Ctrl+Alt+D(切换桌面)代替。
设置bashrc
1 | |
启用systemd
这是废弃的方法:
1 | |
或者(建议使用此方法):MicrosoftDocs/WSL
1 | |
或者直接运行写好的代码,以完成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 | |
重启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文件:
open-wsl.exe打开默认的wsl发行版run-wsl-file.exe运行wsl里面的可执行文件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.conf4-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打开的是这些字符串所代表的文件。
解决方案:
复制vim.exe到同目录并改名为wslterm.exe
程序目录下新建nvim.bat文件,内容为:
@echo off chcp 65001 echo "%~1" > D:\wsl.cache %~d0 cd "%~dp0" wslterm.exe "%~dp1%~n0"同样新建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/路径下并添加可执行权限。在
5-add-open-with-vim-menu.js的基础上创建fix-add-open-with-nvim-menu.js文件,只需要修改文件内容即可:将最后一个vim.exe替换为nvim.bat.可以创建相应的
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.VCLibs和Microsoft.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文件浏览器中,快捷复制文件路径的方法:
- 选中一个或多个文件或目录,按住Shift并鼠标右键,弹出菜单中可以复制为路径。
- 选中文件后,「主页」菜单有「复制路径」的按钮,点击即可。
我不更改WindowsTerminal的任何地方,也不借由其实现所需功能,我注意到Windows的文件浏览器是可以将文件路径快捷复制到系统剪切板的,于是可以利用剪切板进行交互以实现我所需的功能,具体步骤如下:
在Windows文件浏览器中,「主页」菜单的「复制路径」按钮上鼠标右键并点击"添加到快速访问工具栏",然后复制路径可以快速完成。
在wsl发行版中安装xclip,命令为
sudo apt install xclip.在wsl发行版中,新建clippath并编辑:
sudo vim /usr/bin/clippath1
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[@]}在
~/.bash_aliases文件中增加别名设置:1
2
3
4
5
6
7
8
9
10
11
12function 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'执行
source ~/.bashrc命令以应用bash设置。
具体操作有:
- 切换到剪切版中的Windows目录:
首先在Windows文件浏览器中选择文件或目录,复制路径到剪切板,然后在wsl终端中执行cdp即可切换工作目录到复制路径的目录部分。 - 用nvim打开剪切板中的多个路径的文件:
注意,执行cl命令会在一行中输出剪切板中的多个文件路径,根据上述配置的,可以执行 evim `cl` 来用nvim打开剪切板中路径的文件。
执行 vi `cl` 可以在qterminal中的nvim打开这些文件。
注意,vi命令是在我写的"SpaceVim使用教程"中提到的别名(alias)。
可以看到,这基本满足了我们对文件拖曳功能的需求,只是使用方式有点不一样。