wsl2-x-org-环境初始化配置
上一级页面:index-wsl
前言
本文做一些修补,解决在wsl2上可能出现的x-org错误、gtk3错误、以及qt错误。
这些错误对开发者来说很有用处,因为他们要借此来进行调试,但是对最终用户来说就不是这样了,用户不应为他们买单,应当做的是对其中少部分的破坏性错误进行修复,并且屏蔽剩余的大部分错误消息,因为这些错误在用户这无法进行修复
语言和区域设置
必须要检查一遍,网上给出的教程有些问题很大,见linux-修改系统默认语言为中文
设置默认的编辑器
切换到普通用户,在配置文件中写入
export EDITOR='vim'
切换到root用户,重复上述操作
辅助消息总线错误
见x-applications-warn-couldn-t-connect-to-accessibility-bus-failed-to-connect-to-socket
RUNLEVEL错误
正常的从UEFI启动或者grub引导启动时,它应当被自动的设置为3或者5,参考运行级别 - 维基百科,自由的百科全书 (wikipedia.org)
3对应
多用户,正常启动系统
,即所谓的multi-user.target
5对应
多用户,带图形界面
,即所谓的graphical.target
但在WSL中并不是这样,也没多大影响,大部分情况下,在用户运行应用程序时,并不会看到与之相关的报错。参考方案,Getting Up and Running with the Windows Subsystem for Linux - DEV Community
但是以防万一,建议手动设置一下。如果你工作在终端中,即仿造服务器的运行模式,则设置为3(multi-user.target
)。
# 手动指定运行级别
export RUNLEVEL=3
如果你有一个桌面环境(例如gnome-shell或者kde-plasma),则设置为5(graphical.target
)
# 手动指定运行级别
export RUNLEVEL=5
XDG_RUNTIME_DIR错误
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
相关资料
相关的问题见
https://blog.csdn.net/weixin_41194129/article/details/120399123
https://stackoverflow.com/questions/59790350/qstandardpaths-xdg-runtime-dir-not-set-defaulting-to-tmp-runtime-aadithyasb
https://stackoverflow.com/questions/70469462/wsl-ubuntu-20-04-3-error-xdg-runtime-dir-not-set-in-the-environment
问题分析
什么是XDG_RUNTIME_DIR?见
- https://askubuntu.com/questions/872792/what-is-xdg-runtime-dir
$XDG_RUNTIME_DIR
定义相对于应存储哪些特定于用户的非必要运行时文件和其他文件对象(如套接字、命名管道等)的基目录。
该目录必须由用户拥有
,并且他必须是唯一具有读取和写入访问权限的人
。它的Unix访问模式必须是0700
。
它是一个环境变量,在您登录时自动设置。它告诉您运行的任何程序在哪里可以找到用户特定的目录,您可以在其中存储小的临时文件。
注意,正常情况下XDG_RUNTIME_DIR应当在用户交互式登录时,由pam_systemd自动的设置
- pam_systemd,
- XDG_RUNTIME_DIR
- 出处,中文翻译版本:QStandardPaths:未设置 XDG_RUNTIME_DIR,运行 sudo 命令时默认为“/tmp/runtime-root” | 智问智答 (1r1g.cn)
解决方案
首先明确一点,根据XDG_RUNTIME_DIR的设计功能,你并不需要去修复它,只要你能够忍受命令行的报错消息,完全可以放着不管。
XDG_RUNTIME_DIR在设计上,应当且只应当,在本次登录过程中,存储当前用户的,程序运行过程中的,由程序所产生的小文件,这些文件建议在用户登录后立刻进行销毁。根据这个设计功能,在报错消息中的默认存储到/tmp/runtime-username
文件夹中完全是符合功能需求的,并不需要去修复
非要修复这个报错消息,可以接着往下看
- 参考方案,Getting Up and Running with the Windows Subsystem for Linux - DEV Community
- x11 - QStandardPaths:未设置XDG_RUNTIME_DIR,默认为'/tmp/runtime-aadithyasb' - 堆栈溢出 (stackoverflow.com)
- 参考ssh - error: XDG_RUNTIME_DIR not set in the environment. Gtk-WARNING **: cannot open display: - Stack Overflow
导致此报错消息有几种可能
- pam_systemd没有正常的运行,不能自动的生成XDG_RUNTIME_DIR
- 在ssh登录过程中,环境变量没有正确的继承
- 切换用户运行程序,例如
sudo nautilus
,使用root用户来运行程序,却没有传递必要的一些环境变量。
第一种可能,需要检查systemctl和系统的功能是否正常,见wsl2开启systemctl命令简单方法
后面两种可能,可以通过传递环境变量解决,方案如下:
设置env_keep
# 使用下列命令编辑/etc/sudoers
sudo visudo
Defaults env_keep += "DISPLAY XAUTHORITY https_proxy http_proxy"
它还对应一个临时修复方案
DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY https_proxy=$https_proxy http_proxy=$http_proxy your_command
例如
DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY https_proxy=$https_proxy http_proxy=$http_proxy sudo jetbrains-toolbox
重启WSL,问题解决
如果没有效果,那么继续参考下面的方案:
在用户配置文件中写入
# $XDG_RUNTIME_DIR定义相对于应存储哪些特定于用户的非必要运行时文件和其他文件对象(如套接字、命名管道等)的基目录。
# 该目录必须由用户拥有,并且他必须是唯一具有读取和写入访问权限的人。它的Unix访问模式必须是0700。
export XDG_RUNTIME_DIR=/tmp/XDG_RUNTIME_DIR/$USERNAME
之后手动创建这个文件夹,需要注意的是每个用户应当单独创建这个文件夹,隔离开来
首先切换到lamirs用户(用户1)
su - lamirs
mkdir /tmp/XDG_RUNTIME_DIR/$USERNAME
chmod 700 /tmp/XDG_RUNTIME_DIR/$USERNAME
切换到root用户,重复上述操作
注意你的/tmp目录很可能会被定期清空,不同发行版有不同的实现方式,比如在debian/ubuntu系中,会使用systemd-tmpfiles
来定期清空/tmp
。
这时候你可以编写相应规则来重新创建文件夹/tmp/XDG_RUNTIME_DIR/$USERNAME
,或是放到其他目录,比如/opt/tmp/XDG_RUNTIME_DIR/$USERNAME
qt.qpa.xcb: QXcbConnection: XCB error
错误消息类似下面这样的
qt.qpa.xcb: QXcbConnection: XCB error: 3 (BadWindow), sequence: 176, resource id: 7864326, major code: 20 (GetProperty), minor code: 0
我被告知这些消息主要只对开发人员有用,帮助调试问题。
它是一种调试信息
它是一种调试信息
它是一种调试信息
它是一种调试信息
对于用户来说,没有用处,详见Qt - ArchWiki (archlinux.org)
首先编辑 /usr/share/qt5/qtlogging.ini
(以 root 身份)
sudo vim /usr/share/qt5/qtlogging.ini
并添加以下内容
qt.qpa.xcb.xcberror.error=false
qt.qpa.xcb.warning=false
qt.qpa.xcb.error=false
然后尝试安装qt5-default
sudo apt install qt5-default
设置环境变量
export QT_SELECT=qt5
然后设置环境变量到配置文件中,关闭所有qt调试信息,见kde - 如何抑制 QXcbConnection: XCB 错误 - 超级用户 (superuser.com)和Qt - ArchWiki (archlinux.org)
(推荐)完全禁用日志记录:QT_LOGGING_RULES
export QT_LOGGING_RULES='*=false'
要仅禁用调试日志记录,请使用 。QT_LOGGING_RULES="*.debug=false"
Cannot load library libkdeinit5_kded5
报错如下
Could not open kded5 using a library: Cannot load library libkdeinit5_kded5: (libkdeinit5_kded5: 无法打开共享对象文件: 没有那个文件或目录)
尝试重新安装
sudo apt install --reinstall kded5
sudo apt-mark auto kded5
尝试重新配置相关包
sudo dpkg-reconfigure kded5
之后解决报错主体部分
libkdeinit5_kded5: 无法打开共享对象文件: 没有那个文件或目录
查了官方的仓库Ubuntu – 在 focal 中的 kded5 软件包详细信息
kded5_5.68.0-0ubuntu1_amd64.deb Ubuntu 20.04 LTS Download (pkgs.org)
发现根本就没有这个so文件,日!!!
正常情况下,它应当在下面的路径,被包含在kded5
包中
/usr/lib/x86_64-linux-gnu/libkdeinit5_kded5.so
访问URL,这里的focal替换为你的ubuntu版本号,focal为2004
https://packages.ubuntu.com/focal/libs/kded5
查看页面中的文件列表发现确实没有
尝试下载一个旧版本(1804 bionic)的,复制出来
https://packages.ubuntu.com/bionic/libs/kded5
从这里的链接处,右键复制链接,随便一个镜像链接都可以
cd ~
mkdir src
wget http://th.archive.ubuntu.com/ubuntu/pool/universe/k/kded/kded5_5.44.0-0ubuntu1_amd64.deb
dpkg -X ./kded5_5.44.0-0ubuntu1_amd64.deb .
sudo cp ~/src/usr/lib/x86_64-linux-gnu/libkdeinit5_kded5.so /usr/lib/x86_64-linux-gnu/libkdeinit5_kded5.so
问题解决!!
类似的报错:找不到文件: 无法打开共享对象文件: 没有那个文件或目录
您看到的大多数“没有这样的文件或目录”错误都是由于插件的可选deps。如果你想要这些插件,你必须安装pacman在安装软件时告诉你的可选deps。
另外一个相关帖子244318 – x11/kf5-kded: crash on session start (freebsd.org)
此处以找不到libkdeinit5_kded5为例,
Could not open kded5 using a library: Cannot load library libkdeinit5_kded5: (libkdeinit5_kded5: 无法打开共享对象文件: 没有那个文件或目录)
尝试重新安装相关包,通过apt depends查询发现相关包如下
- kded5
- qt5-sqldrivers-sqlite3
- plasma5-kactivitymanagerd
- kf5-kactivities
- kf5-kactivities-stats
sudo apt install --reinstall kded5
sudo apt-mark auto kded5
sudo apt install --reinstall kactivitymanagerd
sudo apt-mark auto kactivitymanagerd
sudo apt install --reinstall kactivities-bin libkf5activitiesstats1
sudo apt-mark auto kactivities-bin libkf5activitiesstats1
尝试重新配置相关包
sudo dpkg-reconfigure kded5
没有解决的话,
也可能是glib的版本问题,如帖子所述244318 – x11/kf5-kded: crash on session start (freebsd.org)
Sep 24 17:49:36 mizar pkg-static[77311]: glib-2.56.3_9,1 deinstalled
Sep 24 17:49:37 mizar pkg-static[77335]: glib-2.66.0_1,1 installed
作者的glib在更新后,问题就消失了
结合我自己的实际经历,很有可能的解释是,
- 原本的
libkdeinit5_kded5.so
中的重要函数被合并到了上游的glib中,导致kded5中不再包含libkdeinit5_kded5.so
。 - 实现相关功能不再需要调用这个
libkdeinit5_kded5.so
,更换了实现方式
这种情况无解了,要么你下载旧版本的kded5包,手动解包,复制对应文件到正确位置,要么等待系统更新到下一个大版本,在系统升级的过程中附带升级glib。
directory /tmp/.ICE-unix will not be created.
_IceTransmkdir: ERROR: euid != 0,directory /tmp/.ICE-unix will not be created.
要么需要更新系统以获取
较新的 /etc/rc.d/cleartmp
,
要么root用户下,手动执行脚本底部执行的操作: xfce4 error (narkive.com)
su - root
# 创建具有正确权限的套接字目录以避免安全问题。
rm -fr /tmp/.X11-unix
rm -fr /tmp/.ICE-unix
rm -fr /tmp/.font-unix
rm -fr /tmp/.XIM-unix
mkdir -m 1777 /tmp/.X11-unix
mkdir -m 1777 /tmp/.ICE-unix
mkdir -m 1777 /tmp/.font-unix
mkdir -m 1777 /tmp/.XIM-unix
failed: Failed to execute program org.bluez.obex: No such file or directory
Activated service 'org.bluez.obex' failed: Failed to execute program org.bluez.obex: No such file or directory
此 bug 已在 bluez - 5.62-0ubuntu1 包中修复
查看自己的版本
sudo apt show bluez
很不幸,我是5.53,低于这个版本的手动修一下
在检查时,这是因为服务定义包含无法解析的行“Exec=@libexecdir@/obexd
”(此占位符应该在构建时替换)。
将“@libexecdir@
”替换为“/usr/lib/bluetooth
”解决了这个问题
(之后需要命令systemctl --user daemon-reload
、systemctl --user restart obex
)。
该错误似乎存在于以下位置:
/usr/share/dbus-1/services/org.bluez.obex.service
解决方案
sudo vim /usr/share/dbus-1/services/org.bluez.obex.service
[D-BUS Service]
Name=org.bluez.obex
Exec=@libexecdir@/obexd
SystemdService=dbus-org.bluez.obex.service
将@libexecdir@
替换为/usr/lib/bluetooth
[D-BUS Service]
Name=org.bluez.obex
Exec=/usr/lib/bluetooth/obexd
SystemdService=dbus-org.bluez.obex.service
重载一下
sudo systemctl --user daemon-reload
sudo systemctl --user restart obex
polkit_agent_listener_register_with_options: assertion 'POLKIT_IS_SUBJECT (subject)' failed
polkit_agent_listener_register_with_options: assertion 'POLKIT_IS_SUBJECT (subject)' failed
参考1580984 – xfce-polkit 直接崩溃 (redhat.com)
排查问题
echo $XDG_SESSION_ID
发现XDG_SESSION_ID
为空
继续检查
echo $XDG_SESSION_TYPE
发现XDG_SESSION_TYPE
为空
问题原因:XDG 环境通常是显示管理器(dm)的工作。 XDG_SESSION_TYPE
和XDG_SESSION_ID
没有被dm正确的设置。
在我这里是sddm,这很明显了,wsl中sddm可以正常的运行,但并不能弹出窗口,先忽略
继续排查
systemctl --user
Failed to list units: Process org.freedesktop.systemd1 exited with status 1
可以看到这里报错了,这个报错很多时候是由于正在尝试使用 Wayland。 事实上,systemd 对 Wayland 会话有特殊处理。
https://www.freedesktop.org/software/systemd/man/pam_systemd.html
pam-kwallet
其中一种可能性是安装了pam-kwallet,它是kde的组成部分
你可以尝试用'pkexec'运行一些东西来测试,即'pkexe id'应该调用pokit,使用xfce-polkit或并要求你进行身份验证然后运行'id'。
我假设那不再起作用了,这让我认为这可能是错误 1581495 的副本
您是否安装了“pam-kwallet”? 如果您禁用或删除该软件包并注销/重新登录,它会开始工作吗?
按照帖子1581495 – lightdm + pam-kwallet causes polkit issues (redhat.com)
查找pam-kwallet
sudo apt search pam kwallet
发现的确安装了
首先切换到root用户
su - root
journalctl -b 0 | grep -i kwallet
给出警告消息
Journal file /var/log/journal/35df541a9d1c9482f308d5cd6277eda8/system@0005e31b40d1db42-33ae9b8a40b3ee47.journal~ uses an unsupported feature, ignoring file.
Use SYSTEMD_LOG_LEVEL=debug journalctl --file=/var/log/journal/35df541a9d1c9482f308d5cd6277eda8/system@0005e31b40d1db42-33ae9b8a40b3ee47.journal~ to see the details.
按照警告消息继续排查
SYSTEMD_LOG_LEVEL=debug journalctl --file=/var/log/journal/35df541a9d1c9482f308d5cd6277eda8/system@0005e31b40d1db42-33ae9b8a40b3ee47.journal~
Journal effective settings seal=no compress=no compress_threshold_bytes=8B
Journal file /var/log/journal/35df541a9d1c9482f308d5cd6277eda8/system@0005e31b40d1db42-33ae9b8a40b3ee47.journal~ has unknown incompatible flags 0xc
Failed to open journal file /var/log/journal/35df541a9d1c9482f308d5cd6277eda8/system@0005e31b40d1db42-33ae9b8a40b3ee47.journal~: 不支持的协议
mmap cache statistics: 0 hit, 1 miss
Failed to open files: 不支持的协议
无果。
按照原帖的说法,可能还涉及到 selinux 问题,但是表现出这种行为的机器(我正在编写它的笔记本电脑)禁用了 SELinux
配置自动解锁kwallet
查询wikiKDE Wallet - ArchWiki (archlinux.org)
- kwallet-pam 与 GnuPG keys 不兼容,所以 KDE Wallet 必须使用
blowfish
加密方式。
查找pam-kwallet
sudo apt search pam kwallet
发现的确安装了
查找kwalletmanager,没有就手动安装
sudo apt search kwalletmanager
打开kwalletmanager
kwalletmanager
新建一个钱包,命名必须为kdewallet
,加密方式必须为blowfish
,密码必须与当前 用户 的密码相同。
- 如果桌面环境用的是 KDE, 建议关闭 KDE Wallet settings 里的 Close when last application stops using it 选项来防止 wallet 在每次被使用(比如获取WiFi密码)之后被关闭。
- 可能需要先把默认创建的 wallet 删除——即删除所有已经储存的密码条目。
- 如果 kwallet Migration Assistant在每次登录之后都要求输入密码,请重命名或删除
~/.kde4/share/apps/kwallet
文件夹.
其余的配置参考wiki KDE Wallet - ArchWiki (archlinux.org)
解决方案
尝试重新安装
sudo apt install --reinstall libpam-kwallet-common libpam-kwallet5 gnome-keyring gnome-keyring-pkcs11 libpam-gnome-keyring ubuntu-keyring kwalletmanager
sudo apt-mark auto libpam-kwallet-common libpam-kwallet5 gnome-keyring gnome-keyrin
g-pkcs11 libpam-gnome-keyring ubuntu-keyring kwalletmanager
sudo apt install --reinstall polkit-kde-agent-1
sudo apt-mark auto polkit-kde-agent-1
查看服务
sudo systemctl status polkit.service
以后再说
xorg.extras.xml: No such file or directory (os error 2)
'/usr/share/X11/xkb/rules/xorg.extras.xml': No such file or directory (os error 2)
排查问题
ll /usr/share/X11/xkb/rules/
发现缺少这个文件
cd /usr/share/X11/xkb/rules/xorg.extras.xml
sudo cp xorg.xml xorg.extras.xml
error while loading shared libraries: libatk-1.0.so.0: cannot open shared object file: No such file or directory
报错消息如下
/node_modules/electron/dist/electron: error while loading shared libraries: libatk-1.0.so.0: cannot open shared object file: No such file or directory
error Command failed with exit code 127.
参考Error while loading shared libraries · Issue #519 · electron/electron-quick-start (github.com)
因为是wsl,所以解决方法不太一样
rm -rdf node_modules
npm install --platform=win32
排查问题
whereis libatk-1.0.so.0
libatk-1.0.so: /usr/lib/x86_64-linux-gnu/libatk-1.0.so.0
参考、引用、致谢
主要参考内容列在文章内