DBUS 乱创记录
dbus 是一种 IPC 机制,由 freedesktop.org 项目提供,用于进程间通信或进程与内核的通信。dbus 支持进程间一对一和多对多的对等通信,在多对多的通信时,需要后台进程的角色去分转消息,当一个进程发消息给另外一个进程时,先发消息到后台进程,再通过后台进程将信息转发到目的进程。dbus 后台进程充当路由器角色。
很多软件都要用到 dbus,比如 gnome。而设置 gnome 无论是样式还是代理,使用 gsettings
还是 dconf
,都要依赖当前用户的 dbus 才能成功设置。最近折腾银河麒麟的代理设置踩了不少坑,下面记录一下。
当前的需求是在 root 用户下,设置 admin 用户的系统代理。几版脚本代码都遇到了问题,第一版脚本直接用 dconf
设置报不存在 dbus。第二版脚本手动拉起 dbus 发现设置能成功 ,但是在 admin 用户已经登陆的情况下,设置不能持久化,注销再登陆又消失了。第三版直接手动设置 dbus 的环境变量,发现 admin 用户的 dbus 是需要 admin 用户登陆后才会自动拉起,如果没登陆就会直接失败。
经过三版的踩坑,大概猜测出用户已经拉起 dbus 的时候再手动拉起会导致冲突使得设置并没有成功更改到配置文件。所以需要先判断用户是否已经拉起 dbus,如果已经拉起,就手动配置 dbus 的环境变量然后再执行修改;如果不存在,就使用 dbus-run-session
手动启动一个临时的 dbus 来设置。以这个思路编写了第四版的脚本成功完成修改。
例子如下:
#!/bin/bash
# 定义dconf设置函数
apply_dconf_settings() {
# 填入自己想要的设置代码
}
# 如果 DBUS_SESSION_BUS_ADDRESS 为空,则尝试按约定补全
if [[ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ]]; then
uid=$(id -u)
fallback_bus="unix:path=/run/user/${uid}/bus"
if [[ -S "/run/user/${uid}/bus" ]]; then
export DBUS_SESSION_BUS_ADDRESS="$fallback_bus"
echo "DBUS_SESSION_BUS_ADDRESS 未设置,已自动导出为 $fallback_bus"
apply_dconf_settings
else
echo "警告:/run/user/${uid}/bus 不存在,将使用 dbus-run-session 启动临时会话..." >&2
# 把函数定义带到子 shell 里,然后执行
dbus-run-session -- bash -c "
$(declare -f apply_dconf_settings)
apply_dconf_settings
"
fi
else
echo "DBUS_SESSION_BUS_ADDRESS 已配置"
apply_dconf_settings
fi
exit 0
看看其他吧