我几乎没有通过 ssh 使用依赖 dbus 的工具(例如pactl
选择音频输出的 pulseaudio 命令行界面)。
我知道如何手动将会话的 DBUS 地址导出到DBUS_SESSION_BUS_ADDRESS
,但几乎任何应用程序仍然会失败并出现类似的消息connection refused at pa_context_new()
。
可悲的是,这完全符合对 dbus、kdbus(和 systemd)的所有保留意见......
那么,要使任何依赖 DBUS 的应用程序通过 ssh 运行,就像在桌面会话中一样,实际上需要哪些步骤?
有没有一种非不稳定、不易出错的方法来获取总线地址,而不依赖于屏幕长的脚本?
除了地址之外,还需要什么才能允许连接?
答案1
帕克特尔才不是依赖于 D-Bus– 这只是它可能用于定位控制套接字的各种方法之一。现在控制套接字始终位于同一位置 – $XDG_RUNTIME_DIR/pulse/native
(从 pulseaudio v3.0 开始)。因此,最初的投诉根本说不通。我确信这strace -e connect pactl info
会揭示“连接被拒绝”错误来自尝试连接到 pulseaudio 本身,而不是连接到 D-Bus。
一个可能的原因:如果 strace 显示 pactl 尝试使用
/var/run/pulse/native
而不是每个用户路径,则可能未设置 $XDG_RUNTIME_DIR。您可以手动设置它(到/run/user/$UID
),但是,最好弄清楚为什么它没有自动设置。$XDG_RUNTIME_DIR 变量由 pam_systemd.so 设置;确保您的
/etc/pam.d/sshd
配置文件最终列出该模块(有时直接列出,但更多时候是通过包含子配置,如system-login
或common-session
)。
也就是说,当你需要使用其他通过 SSH 运行的程序 –做依赖于会话总线 - 有三种常见的选项:
要连接到“新”用户总线:
一些系统/发行版可能已经转向“用户总线”模型,其中每个 UID 只有一个会话总线,而不是多个会话总线。其地址位于
unix:path=/run/user/$UID/bus
dbus-daemon 或kernel:path=/sys/fs/kdbus/$UID-user/bus
kdbus 中。如果未设置 $DBUS_SESSION_BUS_ADDRESS 和 $DISPLAY,最新版本的 sd-bus、libdbus、gdbus 将自动尝试此地址。这使得“用户总线”模型成为您第一个问题的最可靠答案,因为您只需要知道您自己的 UID。(大多数涉及传统“会话总线”模型的方法不能是可靠的,因为可能有任意数量的这样的变量,而不完全是一个......)
要连接到“传统”会话总线:
会话总线地址通常是随机选取的,以避免冲突。但是,出于各种目的(主要是“总线自动启动”功能),该地址存储在
~/.dbus/session-bus/$MACHINE_ID-$DISPLAY
(大约)中。因此,您可以像以前一样手动设置 $DBUS_SESSION_BUS_ADDRESS,但您也可以设置 $DISPLAY,程序将根据 X11 显示找到匹配的会话总线。
要开始新的(专用)会话总线:
dbus-launch --exit-with-session /bin/bash