关于 GUI 应用程序有几个悬而未决的问题,其控制台输出显示类似于以下内容的重复错误:
(XXXX:YYYY): dconf-CRITICAL **: unable to create file '/run/user/NNNN/dconf/user': Permission denied. dconf will not work properly.
或者
(XXXX:YYYY): dconf-CRITICAL **: unable to create directory '/run/user/NNNN/dconf': Permission denied. dconf will not work properly.
其中 XXX 是应用程序名称,YYY 是数字,NNN 是用户 ID 号 (?)。
- 无法创建目录“/run/user/7093511/dconf”:权限被拒绝。 dconf 将无法正常工作
- 收到“无法创建文件'/run/user/1000/dconf/user':权限被拒绝”(适当披露:我三年前的一个问题)
- Mate 桌面在用户切换时会出现没有面板和数十个 caja 窗口的情况?
- 从备用用户运行 X 应用程序时 dconf 失败
- vnc 上黑屏,iLo 上灰屏,可能是 /run/user/1000/dconf/user 问题吗?
这些问题往往没有得到答复,或者得到的答案不能解决问题(或者可能是没有反应的海报)。
我希望引起社区对这个问题的足够关注(如果必要的话可能会提供赏金),以提供对该问题的可能原因的正确描述,并列出应该解决的几个行动(例如在 90% 的情况下),以便将来,人们可以轻松地将这些问题的另一种变体标记为与此问题重复。
答案1
最简单的原因是整个/run/user/<UID>
目录不存在 – 它不是由 systemd-logind 创建的,通常是因为有问题的 UID 没有经过标准的“用户登录”过程,而只是su
'd 或sudo
'd到,而不调用 pam_systemd。
(“权限被拒绝”来自 dconf 尝试 mkdir 所有父目录,但它无法执行此操作,因为 /run 和 /run/user 本身只能由 root 写入。)
当至少创建该 UID 的一个会话时,就会创建此目录 - 同样,当 systemd-logind 看到用户的会话计数下降到 0 时,该目录也会被删除。例如,在您的一篇文章中,使用su -l
而不是su
可以解决问题是因为它使 su 使用不同的 PAM 配置,其中 pam_systemd是已启用。
因此,如果在通过 VNC 使用桌面时开始显示您自己的 UID 的错误消息,则可能意味着整个 VNC 进程树存在于任何 systemd-logind“会话”之外(即启动时未使用 PAM) VNC 服务器),因此不是引用计数的一部分,这会阻止 systemd-logind/run/user/<UID>
在注销时删除目录。
(例如,如果您通过 SSH 连接到远程主机,则会创建用户运行时目录;然后您启动类似“vncserver.service”的内容,一切看起来都很好;但是一旦您与 SSH 断开连接,运行时目录就会被删除再次因为那是你的最后一次会议。)
(您可以在 中看到这一点journalctl
,可能是间接的 – 当名为“UID <UID> 的用户管理器”的“systemd --user”实例启动/停止时,运行时目录会同时创建/删除。)
在这些情况下,使运行时目录“永久”的一种方法是设置 systemd-logind萦绕该用户的标志,使用loginctl enable-linger <USERNAME>
.这将导致该用户的运行时目录(及其systemd --user
实例)在启动时启动并保留到关闭为止。
或者,如果通过 systemd 启动 VNC,PAMName=
则应使用其 .service 参数创建完整的 PAM 会话,该会话将向 systemd-logind 注册,并在 VNC .service 运行时创建运行时目录。
第二个相关原因是 dconf 被告知使用另一个用户的运行时目录。 “/run/user/<UID>”模式不是由 dconf 直接确定的 - 相反,整个路径取自XDG_RUNTIME_DIR
PAM 设置的环境变量。
如果您使用诸如sudo -E
以不同用户身份运行图形程序之类的东西,它们将继承您的所有环境 - 如果它是世界可读的,它们可能能够与您的 $HOME 一起使用,但它们将无法使用您的 $XDG_RUNTIME_DIR因为它只能由您访问(根据设计)。
解决方案是“不要这样做”,即不要让在其他 UID 下运行的程序继承您的 $XDG_RUNTIME_DIR 和相关环境。特别是对于 dconf,如果需要,它将回退到用户的 ~/.cache/dconf(尽管这假设它也没有继承错误的 $HOME)。
答案2
su -l 用户名 -c "(export DISPLAY=:5; dbus-launch --exit-with-session; vncserver -geometry 1792x899 -深度 24 :5)"
命令“dbus-launch --exit-with-session”将 dbus 变量设置为特定于运行 vncserver 的用户,否则它可能会从其他地方获取它们或根本不设置它们。这些需要正确设置,否则您将得到黑屏或权限被拒绝。例如
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1003/bus
答案3
Debian 拉伸
在 12 小时的会话中,我的 xsession-errors 文件有时会被超过 50 万个主题行炸毁(我可以使用tail -f -n +1 .~/xsession-errors | nl
- 临时缓解措施是运行来查看在终端窗口中发生的大屠杀chown -R 1000:1000 /run/user/1000/*
,但是,仍然如此。 ..)。以下是我为阻止这些情况发生而采取的措施的总结:
首先,我清理了所有个人脚本、桌面文件和键盘快捷键片段以查找su
和gksu
命令的出现,并将其替换为su -l
和gksu -l
命令。另外,我用Xfce还有一些/usr/共享/应用程序/需要进行如此更改的桌面文件(主要是我创建/修改的文件)。
然后,由于我的用户桌面文件中至少有一个调用su 至 root可执行文件(在 Debian 中找到菜单包),我复制了/usr/bin/su 到 root到/usr/local/bin/并将其重命名为“su-root-gksu-l”。然后,在该文件中,我替换了以下行:
gksu) gksu -u "$PRIV" "$COMMAND";;
和
gksu) gksu -l -u "$PRIV" "$COMMAND";;
接下来,我清理了所有个人脚本、桌面文件和键盘快捷键片段以使用上述内容su 至 root可执行文件并将对相同内容的任何引用更改为su-root-gksu-l。我做过找到一些桌面文件/usr/共享/应用程序/那个使用了su 至 root脚本,但没有对它们进行任何更改,因为我认为没有必要。我也擦掉了所有的图纳尔自定义操作。
最后,我创建了一个系统范围的别名(插入到等/bash.bashrc文件):function su() { if [[ $1 == "--" ]]; then command su "$@"; else command su -l "$@"; fi; }
仅供参考,还有关于此 shell 函数的附加讨论这里。