WSL2 - Ubuntu 使用记录

1 安装

1.1 通用基本操作

搭配Windows Terminal使用为佳,在微软商店可下载;

然后依照官网描述即可。

命令行中运行wsl --install即可。不过由于想自行指定发行版,于是:

wsl --list --online # 查看分发系统和名字
wsl --install -d Ubuntu-22.04 # 安装一个分发版,-d后为指定分发系统的名字

会进行相应的安装;但之后执行任何wsl命令,都会遭遇

WSL 正在完成升级...
更新失败(退出代码: 1603)。
Error code: Wsl/CallMsi/E_ABORT

重启,过程中windows会更新配置,之后就好了。根据提示再次运行

wsl --install Ubuntu-22.04
# 检测到已存在发行版时会进行Linux安装配置

之后创建UNIX user即可

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!

之后把对应发行版的内容添加到Windows Terminal设置中的默认配置文件即可方便使用

常用命令:

wsl # 开启
wsl -d <发行版名> #指定启动
wsl --list # 查看已有分发版
wsl --list --online # 查看在线有的分发版
wsl --list --verbose # 更详细,包括开关状态
wsl --shutdown # 关闭
# 均可用首字母缩写,如-l -v

1.2 Windows 11 中的变化

【错误记录】错误代码: .. HCS/HCS_E_SERVICE_NOT_AVAILABLE

Windows 11上执行wsl --install后,再其后执行默认Ubuntu安装的过程中出现报错

启用一个或多个功能
[==========================100.0%==========================]
操作成功完成。
请求的操作成功。直到重新启动系统前更改将不会生效。
正在下载: Ubuntu
正在安装: Ubuntu
由于未安装所需的特性,无法启动操作。
错误代码: Wsl/InstallDistro/Service/RegisterDistro/CreateVm/HCS/HCS_E_SERVICE_NOT_AVAILABLE

根据这篇帖子,打开appwiz.cpl,查看左侧菜单栏中“启用或关闭Windows功能”,得到如下图

发现“虚拟机平台”选项倒是开着,但是“适用于Linux的Windows子系统”反而没开。看样子可能就如反馈信息所说,“重新启动系统前更改将不会生效”,所以这个选项没有生效,那么重启估计就好了 \(\to\) 错误的,重启后还是没开,那还是手动开一下吧。

2 系统迁移

2.1 分区间移动

查看wsl状态wsl -l -v;需要关闭wsl --shutdown其实关闭terminal窗口就是shutdown了,无需这样 \(\to\) 并不是,shutdown和关闭窗口还是不一样的)

然后先export再import,网上多有记载:

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 <分发版名> <导入到位置> <导入包位置>

不过这之后会默认切回root用户。如果想要换回自己的用户,对于自己导入的发行版,无法使用命令类似ubuntu2204 config --default-user <用户名>(看到的说法:因为无可用启动器 \(\to\) 又看到说,这个命令得在PowerShell中)

可以在wsl中修改/etc/wsl.conf文件,添加

[user]
default=自己的用户名

然后windows命令行中关一下wsl(wsl --shutdown),重启后就回到自己的用户了(似乎关terminal窗口再进即可)

win11中移动后图标丢失

迁移后,打开Terminal会找不到图标的错误。查看设置中WSL对应的选项,如图所示

图标处路径为 \\?\D:\.... 。笑死,这是注册表表中的写法,KEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss\{GUID}\BasePath 就能看到,但这种写法在此处json里应该不识别。又发现个bug,估计是直接拷贝过来的,招笑微软ざこ~

2.2 导入未打包的ext4.vhdx

重装系统前,应该按上述操作给WSL打包成.tar的,结果忘记了只留下了运行用的ext4.vhdx文件和旧版包(它们本身就在非系统盘里)。
不过这是可以直接复制导入的。见wsl导入已有的ext4.vhdx

在新系统装完wsl后,先安装对应发行版的系统(我这里就导入旧版包了),然后在命令行使用copy将ext4.vhdx文件覆盖过去即可。

copy E:\wsl\Ubuntu-22.04\ext4.vhdx D:\WSL2\Ubuntu-22.04\ext4.vhdx
# copy [old path] [new path] 等一段时间即可
# 没用链接给出的python脚本

3 网络配置

3.1 基本网络状况

wsl2的网络和通常的虚拟机比较像,以我本地为例:

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

多了层主机的中转,所以外部要直接访问wsl2则需要在主机上添加相应路由(大概);而wsl2的代理也不应再127.0.0.1环回指向自己,而应指向主机(也就是nameserver)

3.2 设置代理

发现自己ubuntu上的代理命令都有些错误,导致对github的wget都有错误;对于大小写(http_proxy/HTTP_PROXY)变量,不同应用可能使用不同,应该同时设置上;同时对于wsl,根据上节的原理,代理的ip不应是127.0.0.1而应改为对应的宿主Windows(具体为vEthernet网关,它刚好和wsl中DNS解析所需转发的地址相同,因此可以借用 /etc/resolv.conf 中默认缩写的 nameserver 地址)

所以对于设置proxy,可写脚本proxy_set.sh

#!/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是个人clash客户端配置的端口

# 网上似乎都每个变量都加了'http://',但经测试加不加都行;而且明显加了很别扭且冗余 
# -> 最新测试发现如果不加协议名的话npm install会失败,所以还是加上吧

# 末尾的'/'也一样随意加

查看export变量export -p;删除export变量export -n <变量名>


好像不知哪天起,上述操作完后,WSL中也无法连上外网了。后来经过 检索资料 排查发现,主机处的代理客户端应该打开TUN模式,即虚拟网卡,而且这样之后似乎无需 source ~/proxy_set.sh 也能访问外网了。(不知道是系统变更呢,还是之前只是歪打正着了)

补充:对于Windows 11中新版的WSL,因为开启了Mirror模式,理论上不再需要开代理客户端的TUN模式了,毕竟直接镜像了主机侧的网络,自然就走代理了。如果非要开启TUN模式,需要注意修改 TUN Stack 为 system,因为似乎 gvisor 存在已知bug,它与 WSL2 + fake-ip 组合会导致长链接卡顿,尤其是 SSH 数据流(比如 git clone 会卡住)。DNS处的机制也和过往有些不同了,TUN 模式的 dns fake ip 似乎也有概率出错。(感觉下面的内容也需要好好重写一下了 TODO)

3.3 DNS服务器配置

不知道为什么(可能哪里我做了什么配置),我的WSL会经常性的连不上网(apt下载不了东西),再一检查发现ping www.baidu.com会因域名解析不了导致不通。

于是在/etc/resolv.conf中再加一行nameserver 8.8.8.8手动指定DNS服务器,之后便可ping通百度,apt也能正常下载软件,网络基本回归正常。

讲道理这个文件用于配置系统的域名解析服务器地址,在WSL中被指向了连向宿主机的网关vEthernet;所以是否可以这样认为,WSL将域名解析的工作交给了宿主机一并处理,但不知为何我的Windows系统没有替他完成这个工作或某个环节出错了(我严重怀疑肯定是自己宿主机代理方面配置有问题),所以还是得手动指向标准的8.8.8.8才生效,不过明先发觉这个解析很慢。

同时在/etc/resolv.conf中有这么一段注释。这解释了为什么我每次添加的配置都会被刷掉(大概是每次启动WSL时会生成一份)

# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false

所以根据提示在/etc/wsl.conf中加上相应的配置向,保留自己添加的域名解析服务器配置\(\to\) 这样配置似乎不对的,这样重启wsl后,resolv.conf会直接消失,从而出现问题。

3.4 Windows 11 中的变化

在 Windows 11 中启用WSL后。若主机端开着代理,则甫一打开WSL便会弹出以下报错

wsl: 检测到 localhost 代理配置,但未镜像到 WSL。NAT 模式下的 WSL 不支持 localhost 代理。

这是因为WSL和主机的网络模式默认设置的是NAT模式,即如本节开头“基本网络状况”中所述,WSL通过主机的网络连接进行通信,使用NAT技术通过主机中转与外部网络通信。在这个模式下要想让WSL流量走代理,便得如前在 Windows 10 中所述将localhost写为主机网关。

而在 Win11 中,WSL提供了Mirror模式,它允许WSL与主机共享同一个网络接口,WSL的网络流量将会直接映射到主机系统上,就好像WSL和主机系统是同一个网络设备一样。虽然不知道这会在未来带来什么坑,但不管如何我们都应与时俱进,所以不妨直接改用Mirror模式。

代理方式变更

参照网上资料可知,需要在wsl的配置文件中加上如下内容:

[experimental]
networkingMode=mirrored

## 网上还带有这几项,但似乎这些是原本默认开启的,我感觉没必要写
#dnsTunneling=true
#firewall=true
#autoProxy=true

那么wsl的配置文件是什么应该在哪儿呢?根据 官方文档 - WSL中的高级设置配置 可知,主机端的 %UserProfile%\.wslconfig 和 WSL中的 /etc/wsl.conf 都可以,前者针对全局,后者针对当前WSL分发版,似乎这个修改前者更常用一些。添加完后彻底关闭并重启WSL即可生效。

其实上述操作其实在 Win11 中 已经提供了GUI控制界面 ,在搜索栏输入"WSL Settings"即可进入,在网络选项中便可看到相关选项。修改后并重启WSL即可看到生成了对应的WSL配置文件,不过似乎标签有些不一样而已(从experiment变为wsl2,看来这还是比较新的功能)

DNS解析方式变更

在 Win11 的WSL中,我们还可以发现默认 /etc/resolv.conf 中的 nameserver 项变为了 10.255.255.254,而非原先的 vEthernet 虚拟网关地址。

这大概是默认 dnsTunneling=true 即“启用DNS隧道”的原因,WSL内部的DNS请求会通过专用通道发送到宿主机DNS服务,这个 10.255.255.254 大概就是这个专用通道。而之前则是通过那个虚拟网关转发给主机的。

总而言之这也是新功能,不如顺从。

同时,如果还希望使用老的NAT模式下的代理方式,则代理设置脚本需要修改。毕竟已经不是网关地址了,便不能再用 /etc/resolv.conf ,但可以换一种获取方式。可对 proxy_set.sh 脚本中 host_ip 的获取作如下修改:

host_ip=$(ip route show default | awk '/^default/ {print $3}')

综上,在不考虑新功能可能带来未知麻烦的前提下,新WSL的网络配置可大幅简化,只需修改到Mirror模式即可

4 图形桌面配置

4.1 基本情况

较新的WSL2都会内置GUI支持WSLGd,可以通过ps aux | grep WSLGd查看。如此就允许WSL2中直接运行GUI应用,无需手动配置X服务器:

  • nautilus, gtkwave,直接装了就能用
  • python的matplotlib如果要呈现图片,则需pip装PyQt6
  • 使用OpenGL接口:sudo apt install mesa-utils,可通过glxinfo | grep OpenGL查看,旋转齿轮测试glxgears

较旧的Windows10版本中,可能需要手动装X服务器(如VcXsrv等)

4.2 使用RDP远程桌面

WSL2中配置

# 安装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

Windows端操作:打开远程桌面连接mstsc,连接到<WSL2_IP>:3389,输入WSL2中的用户和密码即可。(不可用localhost:3389,会报错“计算机无法连接到远程计算机的另一个控制台会话,原因是你正在运行一个控制台会话”)

快速获取WSL IP:ip addr show eth0 | grep "inet " | awk '{print $2}' | cut -d/ -f1

image
进入登录界面后,Session选Xorg,用户和口令就是WSL2的。不过如此之后会黑屏然后闪退,这可能是因为xrdp没有Xorg的访问权限:

查看/etc/X11/Xwrapper.config,应该会是allowed_users=console,于是需要将其改为改为anybody。快速修改命令如下

echo "allowed_users=anybody" | sudo tee /etc/X11/Xwrapper.config
sudo systemctl restart xrdp xrdp-sesman
# 重启xrdp,感觉可能手动关windows中rdp窗口估计也行

再次启动就ok了、

image

鼓捣期间还做过的一些操作,不知道有没有影响

  • 添加~/.xsession
    echo "xfce4-session" > ~/.xsession
    chmod +x ~/.xsession
    
  • 添加~/.xinitrc
    echo "exec startxfce4" > ~/.xinitrc
    chmod +x ~/.xinitrc
    
  • 修改/etc/xrdp/startwm.sh:似乎原版默认调用/etc/X11/Xsession,似乎是用于Ubuntu默认桌面环境的
    # 备份一下
    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
    
  • 之前由于Xorg黑屏卡退,选择使用Xvnc,不过如此登录后就是青蓝色背景没有桌面内容被加载,.vnc也没有log;不过不管这个了

5 基本配置

5.1 APT换源

旧版:Ubuntu 24.04前

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

新版

最新 Ubuntu 24.04 之后将逐渐过渡到 deb822 风格的 .sources 文件机制。我们从 sources.list 中可以略知一二

# 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.

新方式下,可以用在 /etc/apt/sources.list.d/ 中增加对应文件的方式来增加源(后面的google-chrome也采用了这个方式),感觉可拓展性增加,更便捷了。

比如,添加清华源

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

5.2 Vim允许鼠标滚轮

home下添加.vimrc set mouse=a

5.3 使用LaTeX

推荐安装tex-live(中文注意需要包括ctex宏包)

# 感觉装全比较好(虽然有3G多,但基本还算快)
sudo apt install texlive-full
# 因为之前只装了texlive-base, texlive-latex-extra等部分内容,结果没有ctex宏包无法编译
# 安装目录在 /usr/share/texlive/

完整版装完后包含ctex宏包,在/usr/share/texlive/tex/texmf-dist/tex/latex/ctex中(和windows下MikTek中ctex包差不多)
此后可能只需要配置一些中文字体(copy一下windows的字体应该就行)

5.4 安装windows字体

直接将windows上的字体弄到/usr/share/fonts中再刷新缓存即可

# 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

5.5 去除Windows中的环境变量

由于两边都装了anaconda,结果wsl中优先引导到了windows这边的

/etc/wsl.conf中继续添加如下内容

[interop]
appendWindowsPath=false

可能并不是简单重启wsl就可以(关闭terminal再打开可能wsl并没有关)
所以需要在cmd中wsl --terminate Ubuntu-22.04后再打开(wsl名称通过wsl --list查看)

不过这样的话,Windows中有些东西的用不了了,比如说code(没想到code用的竟然是win这边的)。
那就把要用的手动加回来,我选择在~/.profile中统一添加,目前需要的也就是vscode

PATH="$PATH:/mnt/c/Users/Xlucidator/AppData/Local/Programs/Microsoft VS Code/bin"

5.6 使用中文输入法

起因是想在wsl2中用typora打字,然后发现输入法还得调。步骤如下:

(1) 安装fcitx,这是一个输入法前端管理框架(必要)

sudo apt install fcitx dbus-x11 im-config fcitx-sunpinyin
# 最后一个 fcitx-sunpinyin 似乎是安装其中一个具体的中文输入法,后文会细说

(2) 编辑/etc/locale.gen文件(似乎不必要

# 找到zh_CN.UTF-8行并解除注释
zh_CN.UTF-8

(3) 修改环境变量,使得各 GUI 应用程序使用 fcitx 作为输入法框架;要对所有shell生效,最简单的就是配置在~/.bashrc中,加完后记得source或新开shell(必要)

# 这些变量分别被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

有教程说配置完要重启wsl,不知是否必要(个人倾向没必要,但会不会和 fcitx-autostart配置与否、变量加在.bashrc还是.profile还是/etc/profile.d中有关,反正无效时再试试)

(4) 在fcitx图形界面中进一步配置(必要)

# 打开fcitx界面,下面几个命令应该都可以
fcitx-config-gtk3
fcitx-configtool

然后加入指定输入法,这步尤其重要,我之前似乎就是这里有问题,导致网上教程对我无效:添加输入法,点去"Only Show Current Language",然后搜pinyin,应该就会出现Sunpinyin选项(这似乎就是第一步apt装的),之后就可以关闭,所有配置结束,应该就可以用拼音输入法了

image

可以发现,之前尝试时我还装了好几个像是Chinese拼音相关的输入法,但它们都没用,虽然原因我不清楚。随后查看并修改Global Config,关注前两个选项 Trigger Input MethodExtra key for trigger input method,分别用于“启动输入法”和“在输入法间切换”,默认配置为 Ctrl+SpaceL_Shift。在Windows 10中,该配置不会和微软输入法产生冲突;但在Windows 11中,该配置会和“使用以前的微软输入法”产生冲突,具体解决方案和个人通用快捷键配置见后。

注意,快捷键Empty对应的是Esc键(别问我是怎么试出来的)

【问题】win11中wsl无法正确激活输入法

在win11中,如果开启“使用以前的微软输入法”,则可能会导致在wsl中,按Ctrl+Space无法激活Sunpingyin输入法,从而使得只能一直使用Sunpingyin输入中文,无法通过Shift切换为中/英文模式。

原因猜测:

  • win11中的旧版微软输入法会捕获Ctrl+Space使其传不到wsl的GUI中,哪怕已经将Ctrl+Space快捷键已禁用
    • 验证:已验证,在fcitx-configtool中重新设置Trigger Input Method键时,Ctrl+Space仅传入了Ctrl;查看了Windows Terminal,没有相应的快捷键
    • 解决方案:姑且将Trigger Input Method键改为Alt+Shift
  • fcitx输入法框架可能并未完全正确工作,还需增加配置
    • 验证:似乎已验证,但原理其实不清楚
    • 解决方案:在.bashrc配置中增加一项export DBUS_SESSION_BUS_ADDRESS="unix:path=$XDG_RUNTIME_DIR/bus"
    • 【新】似乎这样强制指定不对,开启wsl后不会生效,得source一下才行,所以还是不要加了。反正现在使用新版输入法也无妨了。

理解 fcitx-configtool 中 Global Config 的含义,与 ~/.config/fcitx/config 一一对应,下文简称 config 文件:

  • Trigger Input Method:总开关,启用或禁用 fcitx 输入法。对应 config 文件中 TriggerKey
  • Extra key for trigger input method:在 fcitx 输入法中切换。对应 config 文件中 SwitchKey 项,默认 L_SHIFT
  • Enable Hotkey to scroll Between Input Method:我怀疑这个启用了,上条才能生效。对应 config 文件中 IMSwitchKey 项,默认 True
  • 更多选项可在 config 文件中查看,比GUI更多且更好理解一些

综上理解,按下 Trigger Input Method 快捷键启用输入法,随后通过 Extra key for trigger input method 快捷键切换 fcitx 中配置的输入法,据此可自由配置这两个快捷键。我最终选择的配置方式应该能兼容新旧微软输入法,图片如下

同时由于中文使用频率低于英文,所以在第一个 Input Method 页面中,不妨将英文置顶。这样不 Trigger Input Method的情况下默认用英文,Trigger后才切换到 Sunpinyin 输入法,之后再用 Shift 在两者间切换。

关于 Windows 微软输入法吞输入的情况

原先因为新版 win11 的输入法切换窗口时不会保留输入法状态,必然切回到中文,所以启用了旧版的微软输入法。然而发现使用旧版的微软输入法时,无法像Windows Terminal中输入C-SPC,在上节fcitx输入法和emacs中都有所体现,十分不方便。

所以还是换回 win11 新版输入法吧,这样fcitx的快捷键也不用便,emacs的C-SPC也会生效;最新发现切换窗口不保留输入法状态的问题似乎解决了,可能刚更新的吧(并没有,星露谷物语窗口和其他窗口之间切换就会默认改回中文,很麻烦)

查看按键情况:目标SSH终端(WSL,Server)中运行 showkey -a,然后按 Ctrl + Space 进行测试,看是否有 ^@ 出现。从这也可指,如果 Ctrl + Space 失效时,可以用 Ctrl + @ / Ctrl + Shift + @ 代替

5.7 安装Chrome浏览器

之前我一般采用直接下载deb包安装,这次打算将软件加入apt源中。

基本步骤

首先下载谷歌key文件并转写为二进制gpg格式,我们习惯将其置于/usr/share/keyrings下。

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

然后再apt中添加源,绑定key:创建 /etc/apt/sources.list.d/google-chrome.list 文件,并写入内容

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-linux-signing-key.gpg] http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee /etc/apt/sources.list.d/google-chrome.list > /dev/null

以上操作替代了原先 wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - 命令,因为 apt-key 已经因为安全性问题不再被推荐,因而我们采用新方式。

随后即可进行正式的安装

sudo apt update
sudo apt install google-chrome-stable

问题

apt安装时先是报错

E: dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.

按其所说执行命令后,输出报错如下

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

似乎是gpgconf的依赖版本冲突,需要17.3但是本地是17.2。再次执行 sudo apt install google-chrome-stable ,出现进一步报错说明

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).

按它说的尝试使用 apt --fix-broken install 修复,随后再次apt install安装似乎就没问题了。


不对,我装完chrome后,所有GUI界面打开就会卡死。。。重启了WSL解决了。

5.8 Typora生成目录GUI交互

在Typora中,移动图片等功能弹出的目录GUI内容无法进行点击交互。具体行为是:窗口可关闭可失焦聚焦,但点击窗口中的任意内容均无响应,命令行中反馈如下

[11882:0815/182650.224560:ERROR:browser_main_loop.cc(283)] GLib-GObject: ../src/gobject/gsignal.c:2777: instance '0x101401ed4700' has no handler with id '5489'

Typora使用的是Electron框架,它在调用GTK文件选择器信号回调时,找不到已注册的handler,因而报错。这属于典型的 WSLg + GTK3 + Electron 输入事件绑定丢失问题,说是GTK3在WSLg(Wayland后端)下已知的交互bug。

【解决过程】

  • 本来是想继续使用Wayland后端的,毕竟新于X11,于是希望通过 xdg-desktop-portalxdg-desktop-portal-gtk 来提供中间层服务,希望Electron会默认改用portal的API,然后再由portal调用GTK从而绕过交互bug。然而 apt 安装时发现这俩已经安装过了,那么说明Electron就是默认没走xdg-desktop-portal。
  • 所以还是改为使用X11后端,实测运行typora时使用 env GDK_BACKEND=x11 typora 即可解决问题,或许还可以加上 --no-sandbox 来防止沙盒模式下隔离某些IPC通道,似乎snap下不加有概率导致typora闪退。

解决方案

为了方便之后命令行和桌面GUI使用,打算为typora再添加一个覆盖脚本。操作如下

## 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

简单的话其实在bashrc中alias设置一下即可,不过可能对GUI图形界面无效。

posted @ 2023-12-31 21:54  Xlucidator  阅读(1706)  评论(0)    收藏  举报