WSL2 - Ubuntu 使用记录
<h2 id="1-安装">1 安装</h2><h3 id="11-通用基本操作">1.1 通用基本操作</h3>
<p>搭配Windows Terminal使用为佳,在微软商店可下载;</p>
<p>然后依照官网描述即可。</p>
<p>命令行中运行<code>wsl --install</code>即可。不过由于想自行指定发行版,于是:</p>
<pre><code class="language-bash">wsl --list --online # 查看分发系统和名字
wsl --install -d Ubuntu-22.04 # 安装一个分发版,-d后为指定分发系统的名字
</code></pre>
<p>会进行相应的安装;但之后执行任何wsl命令,都会遭遇</p>
<pre><code class="language-bash">WSL 正在完成升级...
更新失败(退出代码: 1603)。
Error code: Wsl/CallMsi/E_ABORT
</code></pre>
<p>重启,过程中windows会更新配置,之后就好了。根据提示再次运行</p>
<pre><code class="language-bash">wsl --install Ubuntu-22.04
# 检测到已存在发行版时会进行Linux安装配置
</code></pre>
<p>之后创建UNIX user即可</p>
<pre><code class="language-bash">Ubuntu 22.04 LTS 已安装。
正在启动 Ubuntu 22.04 LTS...
Installing, this may take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: xlucidator-laptop-wsl2
New password:
Retype new password:
passwd: password updated successfully
Installation successful!
</code></pre>
<p>之后把对应发行版的内容添加到Windows Terminal设置中的默认配置文件即可方便使用</p>
<p>常用命令:</p>
<pre><code class="language-bash">wsl # 开启
wsl -d <发行版名> #指定启动
wsl --list # 查看已有分发版
wsl --list --online # 查看在线有的分发版
wsl --list --verbose # 更详细,包括开关状态
wsl --shutdown # 关闭
# 均可用首字母缩写,如-l -v
</code></pre>
<h3 id="12-windows-11-中的变化">1.2 Windows 11 中的变化</h3>
<h4 id="错误记录错误代码--hcshcs_e_service_not_available">【错误记录】错误代码: .. HCS/HCS_E_SERVICE_NOT_AVAILABLE</h4>
<p>Windows 11上执行<code>wsl --install</code>后,再其后执行默认Ubuntu安装的过程中出现报错</p>
<pre><code class="language-powershell">启用一个或多个功能
[==========================100.0%==========================]
操作成功完成。
请求的操作成功。直到重新启动系统前更改将不会生效。
正在下载: Ubuntu
正在安装: Ubuntu
由于未安装所需的特性,无法启动操作。
错误代码: Wsl/InstallDistro/Service/RegisterDistro/CreateVm/HCS/HCS_E_SERVICE_NOT_AVAILABLE
</code></pre>
<p>根据这篇帖子,打开<code>appwiz.cpl</code>,查看左侧菜单栏中“启用或关闭Windows功能”,得到如下图</p>
<img src="https://img2024.cnblogs.com/blog/2296368/202506/2296368-20250623015544819-259882303.png">
<p>发现“虚拟机平台”选项倒是开着,但是“适用于Linux的Windows子系统”反而没开。看样子可能就如反馈信息所说,“重新启动系统前更改将不会生效”,所以这个选项没有生效,<s>那么重启估计就好了</s> <span class="math inline">\(\to\)</span> 错误的,重启后还是没开,那还是手动开一下吧。</p>
<h2 id="2-系统迁移">2 系统迁移</h2>
<h3 id="21-分区间移动">2.1 分区间移动</h3>
<p>查看wsl状态<code>wsl -l -v</code>;需要关闭<code>wsl --shutdown</code>(<s>其实关闭terminal窗口就是shutdown了,无需这样</s> <span class="math inline">\(\to\)</span> 并不是,shutdown和关闭窗口还是不一样的)</p>
<p>然后先export再import,网上多有记载:</p>
<pre><code class="language-bash">wsl --export Ubuntu-22.04 d:\wsl\Ubuntu2204.tar
# wsl --export <分发版名> <导出到位置>
wsl --unregister Ubuntu-22.04
# wsl --unregister <分发版名>
wsl --import Ubuntu-22.04 d:\wsl\Ubuntu-22.04 d:\wsl\Ubuntu2204.tar
# wsl --import <分发版名> <导入到位置> <导入包位置>
</code></pre>
<p>不过这之后会默认切回root用户。如果想要换回自己的用户,对于自己导入的发行版,无法使用命令类似<code>ubuntu2204 config --default-user <用户名></code>(看到的说法:因为无可用启动器 <span class="math inline">\(\to\)</span> 又看到说,这个命令得在PowerShell中)</p>
<p>可以在wsl中修改<code>/etc/wsl.conf</code>文件,添加</p>
<pre><code class="language-txt">
default=自己的用户名
</code></pre>
<p>然后windows命令行中关一下wsl(<code>wsl --shutdown</code>),重启后就回到自己的用户了(似乎关terminal窗口再进即可)</p>
<h4 id="win11中移动后图标丢失">win11中移动后图标丢失</h4>
<p>迁移后,打开Terminal会找不到图标的错误。查看设置中WSL对应的选项,如图所示</p>
<img src="https://img2024.cnblogs.com/blog/2296368/202507/2296368-20250718091809318-418125777.png">
<p>图标处路径为 <code>\\?\D:\....</code> 。笑死,这是注册表表中的写法,<code>KEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss\{GUID}\BasePath</code> 就能看到,但这种写法在此处json里应该不识别。又发现个bug,估计是直接拷贝过来的,招笑微软ざこ~</p>
<h3 id="22-导入未打包的ext4vhdx">2.2 导入未打包的ext4.vhdx</h3>
<p>重装系统前,应该按上述操作给WSL打包成.tar的,结果忘记了只留下了运行用的ext4.vhdx文件和旧版包(它们本身就在非系统盘里)。<br>
不过这是可以直接复制导入的。见wsl导入已有的ext4.vhdx</p>
<p>在新系统装完wsl后,先安装对应发行版的系统(我这里就导入旧版包了),然后在命令行使用<code>copy</code>将ext4.vhdx文件覆盖过去即可。</p>
<pre><code class="language-bash">copy E:\wsl\Ubuntu-22.04\ext4.vhdx D:\WSL2\Ubuntu-22.04\ext4.vhdx
# copy 等一段时间即可
# 没用链接给出的python脚本
</code></pre>
<h2 id="3-网络配置">3 网络配置</h2>
<h3 id="31-基本网络状况">3.1 基本网络状况</h3>
<p>wsl2的网络和通常的虚拟机比较像,以我本地为例:</p>
<pre><code class="language-txt">example:
wsl2 (eth0:172.19.121.9/20) ----- (vEthernet:172.19.112.1/20) Windows10 (Ethernet 10.1) ----- (...) other LAN of my host
可在network adaptor中验证,或ipconfig
</code></pre>
<p>多了层主机的中转,所以外部要直接访问wsl2则需要在主机上添加相应路由(大概);而wsl2的代理也不应再127.0.0.1环回指向自己,而应指向主机(也就是nameserver)</p>
<h3 id="32-设置代理">3.2 设置代理</h3>
<p>发现自己ubuntu上的代理命令都有些错误,导致对github的wget都有错误;对于大小写(<code>http_proxy</code>/<code>HTTP_PROXY</code>)变量,不同应用可能使用不同,应该同时设置上;同时对于wsl,根据上节的原理,代理的ip不应是<code>127.0.0.1</code>而应改为对应的宿主Windows(具体为vEthernet网关,它刚好和wsl中DNS解析所需转发的地址相同,因此可以借用 <code>/etc/resolv.conf</code> 中默认缩写的 <code>nameserver</code> 地址)</p>
<p>所以对于设置proxy,可写脚本<code>proxy_set.sh</code></p>
<pre><code class="language-bash">#!/bin/bash
# host_ip=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
host_ip=$(grep nameserver /etc/resolv.conf | awk '{print $2}' | head -n 1)
echo "export proxy target: $host_ip"
prot_ip="http://$host_ip"
echo "add protocol: $prot_ip"
export HTTP_PROXY="$prot_ip:7890"
export http_proxy="$prot_ip:7890"
export HTTPS_PROXY="$prot_ip:7890"
export https_proxy="$prot_ip:7890"
# 为了某些域名解析,在resolv.conf中加了其他nameserver,所以完善host_ip的获取方式:head -n 1以获得第一个nameserver的ip(确保是wsl的windows网关)
# 7890是个人***客户端配置的端口
# 网上似乎都每个变量都加了'http://',但经测试加不加都行;而且明显加了很别扭且冗余
# -> 最新测试发现如果不加协议名的话npm install会失败,所以还是加上吧
# 末尾的'/'也一样随意加
</code></pre>
<p>查看export变量<code>export -p</code>;删除export变量<code>export -n <变量名></code></p>
<hr>
<p><font color="red" style="font-weight: bold">好像不知哪天起,上述操作完后,WSL中也无法连上外网了</font>。后来经过 检索资料 排查发现,主机处的代理客户端应该打开TUN模式,即虚拟网卡,而且这样之后似乎无需 <code>source ~/proxy_set.sh</code> 也能访问外网了。(不知道是系统变更呢,还是之前只是歪打正着了)</p>
<p>补充:对于Windows 11中新版的WSL,因为开启了Mirror模式,理论上不再需要开代理客户端的TUN模式了,毕竟直接镜像了主机侧的网络,自然就走代理了。如果非要开启TUN模式,需要注意修改 TUN Stack 为 system,因为似乎 gvisor 存在已知bug,它与 WSL2 + fake-ip 组合会导致长链接卡顿,尤其是 SSH 数据流(比如 <code>git clone</code> 会卡住)。DNS处的机制也和过往有些不同了,TUN 模式的 dns fake ip 似乎也有概率出错。(感觉下面的内容也需要好好重写一下了 TODO)</p>
<h3 id="33-dns服务器配置">3.3 DNS服务器配置</h3>
<p>不知道为什么(可能哪里我做了什么配置),我的WSL会经常性的连不上网(apt下载不了东西),再一检查发现<code>ping www.baidu.com</code>会因域名解析不了导致不通。</p>
<p>于是在<code>/etc/resolv.conf</code>中再加一行<code>nameserver 8.8.8.8</code>手动指定DNS服务器,之后便可ping通百度,apt也能正常下载软件,网络基本回归正常。</p>
<p>讲道理这个文件用于配置系统的域名解析服务器地址,在WSL中被指向了连向宿主机的网关vEthernet;所以是否可以这样认为,WSL将域名解析的工作交给了宿主机一并处理,但不知为何我的Windows系统没有替他完成这个工作或某个环节出错了(我严重怀疑肯定是自己宿主机代理方面配置有问题),所以还是得手动指向标准的8.8.8.8才生效,不过明先发觉这个解析很慢。</p>
<p>同时在<code>/etc/resolv.conf</code>中有这么一段注释。这解释了为什么我每次添加的配置都会被刷掉(大概是每次启动WSL时会生成一份)</p>
<pre><code># This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
#
# generateResolvConf = false
</code></pre>
<p><s>所以根据提示在<code>/etc/wsl.conf</code>中加上相应的配置向,保留自己添加的域名解析服务器配置</s>。 <span class="math inline">\(\to\)</span> 这样配置似乎不对的,这样重启wsl后,resolv.conf会直接消失,从而出现问题。</p>
<h3 id="34-windows-11-中的变化">3.4 Windows 11 中的变化</h3>
<p>在 Windows 11 中启用WSL后。若主机端开着代理,则甫一打开WSL便会弹出以下报错</p>
<pre><code class="language-bash">wsl: 检测到 localhost 代理配置,但未镜像到 WSL。NAT 模式下的 WSL 不支持 localhost 代理。
</code></pre>
<p>这是因为WSL和主机的<strong>网络模式</strong>默认设置的是<strong>NAT模式</strong>,即如本节开头“基本网络状况”中所述,WSL通过主机的网络连接进行通信,使用NAT技术通过主机中转与外部网络通信。在这个模式下要想让WSL流量走代理,便得如前在 Windows 10 中所述将localhost写为主机网关。</p>
<p>而在 Win11 中,WSL提供了<strong>Mirror模式</strong>,它允许WSL与主机共享同一个网络接口,WSL的网络流量将会直接映射到主机系统上,就好像WSL和主机系统是同一个网络设备一样。虽然不知道这会在未来带来什么坑,但不管如何我们都应与时俱进,所以不妨直接改用Mirror模式。</p>
<h4 id="代理方式变更">代理方式变更</h4>
<p>参照网上资料可知,需要在wsl的配置文件中加上如下内容:</p>
<pre><code>
networkingMode=mirrored
## 网上还带有这几项,但似乎这些是原本默认开启的,我感觉没必要写
#dnsTunneling=true
#firewall=true
#autoProxy=true
</code></pre>
<p>那么wsl的配置文件是什么应该在哪儿呢?根据 官方文档 - WSL中的高级设置配置 可知,主机端的 <code>%UserProfile%\.wslconfig</code> 和 WSL中的 <code>/etc/wsl.conf</code> 都可以,前者针对全局,后者针对当前WSL分发版,似乎这个修改前者更常用一些。添加完后彻底关闭并重启WSL即可生效。</p>
<p>其实上述操作其实在 Win11 中 已经提供了GUI控制界面 ,在搜索栏输入"WSL Settings"即可进入,在网络选项中便可看到相关选项。修改后并重启WSL即可看到生成了对应的WSL配置文件,不过似乎标签有些不一样而已(从experiment变为wsl2,看来这还是比较新的功能)</p>
<img src="https://img2024.cnblogs.com/blog/2296368/202506/2296368-20250627012555397-403111785.png">
<h4 id="dns解析方式变更">DNS解析方式变更</h4>
<p>在 Win11 的WSL中,我们还可以发现默认 <code>/etc/resolv.conf</code> 中的 <code>nameserver</code> 项变为了 <code>10.255.255.254</code>,而非原先的 vEthernet 虚拟网关地址。</p>
<p>这大概是默认 <code>dnsTunneling=true</code> 即“启用DNS隧道”的原因,WSL内部的DNS请求会通过<strong>专用通道</strong>发送到宿主机DNS服务,这个 <code>10.255.255.254</code> 大概就是这个专用通道。而之前则是通过那个虚拟网关转发给主机的。</p>
<p>总而言之这也是新功能,不如顺从。</p>
<p>同时,如果<strong>还希望使用老的NAT模式下的代理方式</strong>,则代理设置脚本需要修改。毕竟已经不是网关地址了,便不能再用 <code>/etc/resolv.conf</code> ,但可以换一种获取方式。可对 <code>proxy_set.sh</code> 脚本中 <code>host_ip</code> 的获取作如下修改:</p>
<pre><code class="language-bash">host_ip=$(ip route show default | awk '/^default/ {print $3}')
</code></pre>
<blockquote>
<p>综上,在不考虑新功能可能带来未知麻烦的前提下,新WSL的网络配置可大幅简化,<strong>只需修改到Mirror模式即可</strong>。</p>
</blockquote>
<h2 id="4-图形桌面配置">4 图形桌面配置</h2>
<h3 id="41-基本情况">4.1 基本情况</h3>
<p>较新的WSL2都会内置GUI支持<code>WSLGd</code>,可以通过<code>ps aux | grep WSLGd</code>查看。如此就允许WSL2中直接运行GUI应用,无需手动配置X服务器:</p>
<ul>
<li>如<code>nautilus</code>, <code>gtkwave</code>,直接装了就能用</li>
<li>python的matplotlib如果要呈现图片,则需pip装PyQt6</li>
<li>使用OpenGL接口:<code>sudo apt install mesa-utils</code>,可通过<code>glxinfo | grep OpenGL</code>查看,旋转齿轮测试<code>glxgears</code></li>
</ul>
<p>较旧的Windows10版本中,可能需要手动装X服务器(如VcXsrv等)</p>
<h3 id="42-使用rdp远程桌面">4.2 使用RDP远程桌面</h3>
<p>WSL2中配置</p>
<pre><code class="language-bash"># 安装GUI桌面环境:轻量级xfce4, KDE完整kubuntu-desktop,GNOME完整ubuntu-desktop
sudo apt install xfce4 xfce4-goodies # 后者是增强 xfce 桌面环境功能的一些工具
# 安装xrdp
sudo apt install xrdp
# 启动xrdp
sudo service xrdp start
</code></pre>
<p>Windows端操作:打开远程桌面连接mstsc,连接到<code><WSL2_IP>:3389</code>,输入WSL2中的用户和密码即可。(不可用<code>localhost:3389</code>,会报错“计算机无法连接到远程计算机的另一个控制台会话,原因是你正在运行一个控制台会话”)</p>
<p>快速获取WSL IP:<code>ip addr show eth0 | grep "inet " | awk '{print $2}' | cut -d/ -f1</code></p>
<p><img src="https://img2024.cnblogs.com/blog/2296368/202502/2296368-20250216162528954-1158084266.png"><br>
进入登录界面后,Session选Xorg,用户和口令就是WSL2的。不过如此之后会黑屏然后闪退,这可能是因为xrdp没有Xorg的访问权限:</p>
<p>查看<code>/etc/X11/Xwrapper.config</code>,应该会是<code>allowed_users=console</code>,于是需要将其改为改为<code>anybody</code>。快速修改命令如下</p>
<pre><code class="language-bash">echo "allowed_users=anybody" | sudo tee /etc/X11/Xwrapper.config
sudo systemctl restart xrdp xrdp-sesman
# 重启xrdp,感觉可能手动关windows中rdp窗口估计也行
</code></pre>
<p>再次启动就ok了、</p>
<p><img src="https://img2024.cnblogs.com/blog/2296368/202502/2296368-20250216170841084-402785660.png"></p>
<p>鼓捣期间还做过的一些操作,不知道有没有影响</p>
<ul>
<li>添加<code>~/.xsession</code><pre><code class="language-bash">echo "xfce4-session" > ~/.xsession
chmod +x ~/.xsession
</code></pre>
</li>
<li>添加<code>~/.xinitrc</code><pre><code class="language-bash">echo "exec startxfce4" > ~/.xinitrc
chmod +x ~/.xinitrc
</code></pre>
</li>
<li>修改<code>/etc/xrdp/startwm.sh</code>:似乎原版默认调用<code>/etc/X11/Xsession</code>,似乎是用于Ubuntu默认桌面环境的<pre><code class="language-bash"># 备份一下
sudo cp /etc/xrdp/startwm.sh /etc/xrdp/startwm.sh.bak
# 手动修改/etc/xrdp/startwm.sh有效内容为如下所示:
unset DBUS_SESSION_BUS_ADDRESS
unset XDG_RUNTIME_DIR
startxfce4
</code></pre>
</li>
<li>之前由于Xorg黑屏卡退,选择使用Xvnc,不过如此登录后就是青蓝色背景没有桌面内容被加载,.vnc也没有log;不过不管这个了</li>
</ul>
<h2 id="5-基本配置">5 基本配置</h2>
<h3 id="51-apt换源">5.1 APT换源</h3>
<h4 id="旧版ubuntu-2404前">旧版:Ubuntu 24.04前</h4>
<pre><code class="language-bash">sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo vim /etc/apt/sources.list
# 加入源
'''
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble-security main restricted universe multiverse
noble noble-updates noble-backports noble-security
'''
sudo apt update
</code></pre>
<h4 id="新版">新版</h4>
<p>最新 Ubuntu 24.04 之后将逐渐过渡到 deb822 风格的 <code>.sources</code> 文件机制。我们从 <code>sources.list</code> 中可以略知一二</p>
<pre><code># Ubuntu sources have moved to the /etc/apt/sources.list.d/ubuntu.sources
# file, which uses the deb822 format. Use deb822-formatted .sources files
# to manage package sources in the /etc/apt/sources.list.d/ directory.
# See the sources.list(5) manual page for details.
</code></pre>
<p>新方式下,可以用在 <code>/etc/apt/sources.list.d/</code> 中增加对应文件的方式来增加源(后面的google-chrome也采用了这个方式),感觉可拓展性增加,更便捷了。</p>
<p>比如,添加清华源</p>
<pre><code class="language-bash">sudo tee /etc/apt/sources.list.d/tsinghua.sources > /dev/null <<EOF
Types: deb deb-src
URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu/
Suites: noble noble-updates noble-backports noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
EOF
</code></pre>
<h3 id="52-vim允许鼠标滚轮">5.2 Vim允许鼠标滚轮</h3>
<p>home下添加.vimrc <code>set mouse=a</code></p>
<h3 id="53-使用latex">5.3 使用LaTeX</h3>
<p>推荐安装tex-live(中文注意需要包括ctex宏包)</p>
<pre><code class="language-bash"># 感觉装全比较好(虽然有3G多,但基本还算快)
sudo apt install texlive-full
# 因为之前只装了texlive-base, texlive-latex-extra等部分内容,结果没有ctex宏包无法编译
# 安装目录在 /usr/share/texlive/
</code></pre>
<p>完整版装完后包含ctex宏包,在<code>/usr/share/texlive/tex/texmf-dist/tex/latex/ctex</code>中(和windows下MikTek中ctex包差不多)<br>
此后可能只需要配置一些中文字体(copy一下windows的字体应该就行)</p>
<h3 id="54-安装windows字体">5.4 安装windows字体</h3>
<p>直接将windows上的字体弄到/usr/share/fonts中再刷新缓存即可</p>
<pre><code class="language-bash"># Windows字体库在C:\Windows\Fonts;则挂载在wsl中一般为/mnt/c/Windows/Fonts
# Ubuntu中字体在/usr/share/fonts中
### step1: 搞到字体
# 可直接软链接一份到ubuntu
sudo ln -s /mnt/c/Windows/Fonts /usr/share/fonts/windowsfonts
# 或者拷贝过去(怂,不想再有关联选了这个方式)
sudo mkdir /usr/share/fonts/windowsfonts
sudo cp /mnt/c/Windows/Fonts/* /usr/share/fonts/windowsfonts/
### step2:刷新
# 重新生成fontconfig缓存
fc-cache
</code></pre>
<h3 id="55-去除windows中的环境变量">5.5 去除Windows中的环境变量</h3>
<blockquote>
<p>由于两边都装了anaconda,结果wsl中优先引导到了windows这边的</p>
</blockquote>
<p>在<code>/etc/wsl.conf</code>中继续添加如下内容</p>
<pre><code class="language-txt">
appendWindowsPath=false
</code></pre>
<p>可能并不是简单重启wsl就可以(关闭terminal再打开可能wsl并没有关)<br>
所以需要在cmd中<code>wsl --terminate Ubuntu-22.04</code>后再打开(wsl名称通过<code>wsl --list</code>查看)</p>
<p>不过这样的话,Windows中有些东西的用不了了,比如说code(没想到code用的竟然是win这边的)。<br>
那就把要用的手动加回来,我选择在<code>~/.profile</code>中统一添加,目前需要的也就是vscode</p>
<pre><code class="language-txt">PATH="$PATH:/mnt/c/Users/Xlucidator/AppData/Local/Programs/Microsoft VS Code/bin"
</code></pre>
<h3 id="56-使用中文输入法">5.6 使用中文输入法</h3>
<p>起因是想在wsl2中用typora打字,然后发现输入法还得调。步骤如下:</p>
<p>(1) 安装fcitx,这是一个输入法前端管理框架(必要)</p>
<pre><code class="language-bash">sudo apt install fcitx dbus-x11 im-config fcitx-sunpinyin
# 最后一个 fcitx-sunpinyin 似乎是安装其中一个具体的中文输入法,后文会细说
</code></pre>
<p>(2) 编辑<code>/etc/locale.gen</code>文件(<strong>似乎不必要</strong>)</p>
<pre><code class="language-bash"># 找到zh_CN.UTF-8行并解除注释
zh_CN.UTF-8
</code></pre>
<p>(3) 修改环境变量,使得各 GUI 应用程序使用 fcitx 作为输入法框架;要对所有shell生效,最简单的就是配置在<code>~/.bashrc</code>中,加完后记得source或新开shell(必要)</p>
<pre><code class="language-bash"># 这些变量分别被GTK、QT、X11、其他应用所使用,配置输入法框架
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export DefaultIMModule=fcitx
# export DBUS_SESSION_BUS_ADDRESS="unix:path=$XDG_RUNTIME_DIR/bus" # 新增,似乎加了才完全起效(见后)# 新新,不加了不加了,强制指定会有问题
fcitx-autostart &>/dev/null
# fcitx-autostart也是需要的,用于启动fcitx后端,否则D-Bus找不到这个进程,不启动当然起不了作用
# fcitx-configtool也会报错,类似
# ** (fcitx-config-gtk3:7250): WARNING **: 02:59:06.646: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.fcitx.Fcitx-0 was not provided by any .service files
</code></pre>
<p>有教程说配置完要重启wsl,不知是否必要(个人倾向没必要,但会不会和 fcitx-autostart配置与否、变量加在<code>.bashrc</code>还是<code>.profile</code>还是<code>/etc/profile.d</code>中有关,反正无效时再试试)</p>
<p>(4) 在fcitx图形界面中进一步配置(必要)</p>
<pre><code class="language-bash"># 打开fcitx界面,下面几个命令应该都可以
fcitx-config-gtk3
fcitx-configtool
</code></pre>
<p>然后加入指定输入法,这步<strong>尤其重要</strong>,我之前似乎就是这里有问题,导致网上教程对我无效:添加输入法,点去"Only Show Current Language",然后搜pinyin,应该就会出现<code>Sunpinyin</code>选项(这似乎就是第一步apt装的),之后就可以关闭,<strong>所有配置结束,应该就可以用拼音输入法了</strong>。</p>
<p><img src="https://img2024.cnblogs.com/blog/2296368/202505/2296368-20250509214109982-1116115830.png"></p>
<p>可以发现,之前尝试时我还装了好几个像是Chinese拼音相关的输入法,<strong>但它们都没用</strong>,虽然原因我不清楚。随后查看并修改Global Config,关注前两个选项 <code>Trigger Input Method</code> 和 <code>Extra key for trigger input method</code>,分别用于“启动输入法”和“在输入法间切换”,默认配置为 <code>Ctrl+Space</code> 和 <code>L_Shift</code>。在Windows 10中,该配置不会和微软输入法产生冲突;但在Windows 11中,该配置会和“使用以前的微软输入法”产生冲突,具体解决方案和个人通用快捷键配置见后。</p>
<p>注意,快捷键<code>Empty</code>对应的是Esc键(别问我是怎么试出来的)</p>
<h4 id="问题win11中wsl无法正确激活输入法">【问题】win11中wsl无法正确激活输入法</h4>
<p>在win11中,如果开启“使用以前的微软输入法”,则可能会导致在wsl中,按Ctrl+Space无法激活Sunpingyin输入法,从而使得只能一直使用Sunpingyin输入中文,无法通过Shift切换为中/英文模式。</p>
<p>原因猜测:</p>
<ul>
<li><strong>win11</strong>中的旧版微软输入法会捕获Ctrl+Space使其传不到wsl的GUI中,哪怕已经将Ctrl+Space快捷键已禁用
<ul>
<li><strong>验证</strong>:已验证,在fcitx-configtool中重新设置<code>Trigger Input Method</code>键时,Ctrl+Space仅传入了Ctrl;查看了Windows Terminal,没有相应的快捷键</li>
<li><strong>解决方案</strong>:姑且将Trigger Input Method键改为<code>Alt+Shift</code></li>
</ul>
</li>
<li>fcitx输入法框架可能并未完全正确工作,还需增加配置
<ul>
<li><strong>验证</strong>:似乎已验证,但原理其实不清楚</li>
<li><strong>解决方案</strong>:在<code>.bashrc</code>配置中增加一项<code>export DBUS_SESSION_BUS_ADDRESS="unix:path=$XDG_RUNTIME_DIR/bus"</code></li>
<li>【新】似乎这样强制指定不对,开启wsl后不会生效,得source一下才行,所以还是不要加了。反正现在使用新版输入法也无妨了。</li>
</ul>
</li>
</ul>
<p>理解 fcitx-configtool 中 <strong>Global Config</strong> 的含义,与 <code>~/.config/fcitx/config</code> 一一对应,下文简称 config 文件:</p>
<ul>
<li>Trigger Input Method:总开关,启用或禁用 fcitx 输入法。对应 config 文件中 <code>TriggerKey</code> 项</li>
<li>Extra key for trigger input method:在 fcitx 输入法中切换。对应 config 文件中 <code>SwitchKey</code> 项,默认 <code>L_SHIFT</code></li>
<li>Enable Hotkey to scroll Between Input Method:我怀疑这个启用了,上条才能生效。对应 config 文件中 <code>IMSwitchKey</code> 项,默认 <code>True</code></li>
<li>更多选项可在 config 文件中查看,比GUI更多且更好理解一些</li>
</ul>
<p>综上理解,按下 <code>Trigger Input Method</code> 快捷键启用输入法,随后通过 <code>Extra key for trigger input method</code> 快捷键切换 fcitx 中配置的输入法,据此可自由配置这两个快捷键。我最终选择的配置方式应该能兼容新旧微软输入法,图片如下</p>
<img src="https://img2024.cnblogs.com/blog/2296368/202507/2296368-20250713100824284-1051122666.png">
<p>同时由于中文使用频率低于英文,所以在第一个 <code>Input Method</code> 页面中,不妨将<strong>英文置顶</strong>。这样不 Trigger Input Method的情况下默认用英文,Trigger后才切换到 Sunpinyin 输入法,之后再用 Shift 在两者间切换。</p>
<h4 id="关于-windows-微软输入法吞输入的情况">关于 Windows 微软输入法吞输入的情况</h4>
<p>原先因为新版 win11 的输入法切换窗口时不会保留输入法状态,必然切回到中文,所以启用了旧版的微软输入法。然而发现使用旧版的微软输入法时,无法像Windows Terminal中输入C-SPC,在上节fcitx输入法和emacs中都有所体现,十分不方便。</p>
<p>所以还是换回 win11 新版输入法吧,这样fcitx的快捷键也不用便,emacs的C-SPC也会生效;最新发现切换窗口不保留输入法状态的问题似乎解决了,可能刚更新的吧(并没有,星露谷物语窗口和其他窗口之间切换就会默认改回中文,很麻烦)</p>
<p>查看按键情况:目标SSH终端(WSL,Server)中运行 <code>showkey -a</code>,然后按 Ctrl + Space 进行测试,看是否有 <code>^@</code> 出现。从这也可指,如果 Ctrl + Space 失效时,可以用 Ctrl + @ / Ctrl + Shift + @ 代替</p>
<h3 id="57-安装chrome浏览器">5.7 安装Chrome浏览器</h3>
<p>之前我一般采用直接下载deb包安装,这次打算将软件加入apt源中。</p>
<h4 id="基本步骤">基本步骤</h4>
<p>首先下载谷歌key文件并转写为二进制gpg格式,我们习惯将其置于/usr/share/keyrings下。</p>
<pre><code class="language-bash">curl -fsSL https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor | sudo tee /usr/share/keyrings/google-linux-signing-key.gpg > /dev/null
</code></pre>
<p>然后再apt中添加源,绑定key:创建 <code>/etc/apt/sources.list.d/google-chrome.list</code> 文件,并写入内容</p>
<pre><code class="language-bash">echo "deb http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee /etc/apt/sources.list.d/google-chrome.list > /dev/null
</code></pre>
<blockquote>
<p>以上操作替代了原先 <code>wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - </code> 命令,因为 <code>apt-key</code> 已经因为安全性问题不再被推荐,因而我们采用新方式。</p>
</blockquote>
<p>随后即可进行正式的安装</p>
<pre><code class="language-bash">sudo apt update
sudo apt install google-chrome-stable
</code></pre>
<h4 id="问题">问题</h4>
<p>apt安装时先是报错</p>
<pre><code class="language-bash">E: dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.
</code></pre>
<p>按其所说执行命令后,输出报错如下</p>
<pre><code class="language-bash">dpkg: dependency problems prevent configuration of gpg-agent:
gpg-agent depends on gpgconf (= 2.4.4-2ubuntu17.3); however:
Version of gpgconf on system is 2.4.4-2ubuntu17.2.
...
Errors were encountered while processing:
gpg-agent
gpg-wks-client
gpgsm
dirmngr
</code></pre>
<p>似乎是gpgconf的依赖版本冲突,需要17.3但是本地是17.2。再次执行 <code>sudo apt install google-chrome-stable</code> ,出现进一步报错说明</p>
<pre><code class="language-bash">You might want to run 'apt --fix-broken install' to correct these.
The following packages have unmet dependencies:
dirmngr : Depends: gpgconf (= 2.4.4-2ubuntu17.3) but 2.4.4-2ubuntu17.2 is to be installed
gnupg : Depends: dirmngr (< 2.4.4-2ubuntu17.2.1~) but 2.4.4-2ubuntu17.3 is to be installed
Depends: gnupg-utils (< 2.4.4-2ubuntu17.2.1~) but 2.4.4-2ubuntu17.3 is to be installed
Depends: gpg (< 2.4.4-2ubuntu17.2.1~) but 2.4.4-2ubuntu17.3 is to be installed
Depends: gpg-agent (< 2.4.4-2ubuntu17.2.1~) but 2.4.4-2ubuntu17.3 is to be installed
Depends: gpgsm (< 2.4.4-2ubuntu17.2.1~) but 2.4.4-2ubuntu17.3 is to be installed
Recommends: gpg-wks-client (< 2.4.4-2ubuntu17.2.1~) but 2.4.4-2ubuntu17.3 is to be installed
google-chrome-stable : Depends: fonts-liberation but it is not going to be installed
Depends: libnspr4 (>= 2:4.9-2~) but it is not going to be installed
Depends: libnss3 (>= 2:3.35) but it is not going to be installed
Depends: xdg-utils (>= 1.0.2) but it is not going to be installed
gpg : Depends: gpgconf (= 2.4.4-2ubuntu17.3) but 2.4.4-2ubuntu17.2 is to be installed
gpg-agent : Depends: gpgconf (= 2.4.4-2ubuntu17.3) but 2.4.4-2ubuntu17.2 is to be installed
gpgsm : Depends: gpgconf (= 2.4.4-2ubuntu17.3) but 2.4.4-2ubuntu17.2 is to be installed
E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution).
</code></pre>
<p>按它说的尝试使用 <code>apt --fix-broken install</code> 修复,随后再次apt install安装似乎就没问题了。</p>
<hr>
<p>不对,我装完chrome后,所有GUI界面打开就会卡死。。。重启了WSL解决了。</p>
<h3 id="58-typora生成目录gui交互">5.8 Typora生成目录GUI交互</h3>
<p>在Typora中,移动图片等功能弹出的目录GUI内容无法进行点击交互。具体行为是:窗口可关闭可失焦聚焦,但点击窗口中的任意内容均无响应,命令行中反馈如下</p>
<pre><code> GLib-GObject: ../src/gobject/gsignal.c:2777: instance '0x101401ed4700' has no handler with id '5489'
</code></pre>
<p>Typora使用的是Electron框架,它在调用GTK文件选择器信号回调时,找不到已注册的handler,因而报错。这属于典型的 WSLg + GTK3 + Electron 输入事件绑定丢失问题,说是GTK3在WSLg(Wayland后端)下已知的交互bug。</p>
<p>【解决过程】</p>
<ul>
<li>本来是想继续使用Wayland后端的,毕竟新于X11,于是希望通过 <code>xdg-desktop-portal</code> 和 <code>xdg-desktop-portal-gtk</code> 来提供中间层服务,希望Electron会默认改用portal的API,然后再由portal调用GTK从而绕过交互bug。然而 apt 安装时发现这俩已经安装过了,那么说明Electron就是默认没走xdg-desktop-portal。</li>
<li>所以还是改为使用X11后端,实测运行typora时使用 <code>env GDK_BACKEND=x11 typora</code> 即可解决问题,或许还可以加上 <code>--no-sandbox</code> 来防止沙盒模式下隔离某些IPC通道,似乎snap下不加有概率导致typora闪退。</li>
</ul>
<h4 id="解决方案">解决方案</h4>
<p>为了方便之后命令行和桌面GUI使用,打算为typora再添加一个覆盖脚本。操作如下</p>
<pre><code class="language-bash">## 1. 查找typora位置
which typora# 我用snap装的所以应该就是 /snap/bin/typora
## 2. 创建覆盖脚本,只要PATH中位置在/snap/bin之前就行
## 我原本想选择/usr/bin,但其他方式安装的typora可能会在此处,防止未来冲突,还是整个自定义bin目录吧
mkdir -p ~/bin
cat > ~/bin/typora << 'EOF'
env GDK_BACKEND=x11 /snap/bin/typora --no-sandbox "$@"
EOF
chmod +x ~/bin/typora
## 3. 添加环境变量,在/snap/bin之前
## 其实~/bin的话,在~/.profile中已经有定义说如果存在就加入到PATH中,可以不用自己加;不过这样非登录shell可能用不了,看情况改就行
grep -qxF 'export PATH="$HOME/bin:$PATH"' ~/.bashrc || \
cat >> ~/.bashrc << 'EOF'
# fix typora bug with gtk and wayland
export PATH="$HOME/bin:$PATH"
EOF
# 空行是为了补上空行和文件尾部空行
source ~/.bashrc
</code></pre>
<p>简单的话其实在bashrc中alias设置一下即可,不过可能对GUI图形界面无效。</p><br><br>
来源:https://www.cnblogs.com/xlucidator/p/17938073
頁:
[1]