我正在尝试通过 X11 转发和 SSH 运行各种 Gnome 应用程序。某些应用程序会导致首先生成“dbus-launch”应用程序。问题是当退出 X 应用程序时 dbus-launch 不会关闭,因此必须在 SSH 会话可以正确关闭之前终止。
我认为问题是 X/Gnome 应用程序无法与主消息总线守护进程连接,因此必须启动它们自己的副本?我怎样才能解决这个问题?或者我错过了什么?
这是一个例子。我启用了 X11 转发,似乎一切正常。
[me@host ~]$ gnome-calculator &
[1] 4803
Run Code Online (Sandbox Code Playgroud)
(这里 gcalctool 程序启动并显示到我的删除 X 服务器(Xming))
[me@host ~]$ ps
PID TTY TIME CMD
4706 pts/0 00:00:00 bash
4803 pts/0 00:00:00 gnome-calculator
4807 pts/0 00:00:00 dbus-launch
4870 pts/0 00:00:00 ps
Run Code Online (Sandbox Code Playgroud)
(现在,在远程会话中关闭 gcalctool 应用程序后)
[me@host ~]$ ps
PID TTY TIME CMD
4706 pts/0 00:00:00 bash
4807 pts/0 00:00:00 dbus-launch
4898 pts/0 00:00:00 ps
Run Code Online (Sandbox Code Playgroud)
请注意, dbus-launch 仍处于活动状态。最糟糕的是,这会阻止 SSH 连接正确关闭,直到它被终止。
请注意,系统范围的消息守护程序正在运行,如下所示:
[me@host ~]$ ps ax
4696 ? Ssl 0:00 dbus-daemon --system
Run Code Online (Sandbox Code Playgroud)
我在这里缺少什么?我以前从未见过这种行为。据推测,我只见过可以不受阻碍地连接到消息总线守护进程的应用程序?我在 /etc/dbus-1 中寻找答案,但不知道该寻找什么。
在此先感谢您的帮助。
[编辑]
好的,我意识到我遇到了一个常见问题。这似乎是一个相当普遍的行为,但没有一个好的解决方案。我遇到了 SSH 挂起,因为 dbus-launch 在 tty 中仍然处于活动状态。但是似乎没有什么好方法可以让 dbus-launch 安静地发生。
查看 /etc/X11/xinit/xinitrc.d/00-start-message-bus.sh 提供了一些关于“正常”X 会话应该发生什么的线索。这当然在仅将 X 应用程序调用到远程 X 服务器时不起作用。
作为临时解决方法,我已将其添加到我的 .bash_logout 中:
# ~/.bash_logout
pkill -u $USER -t `tty | cut -d '/' -f 3,4` dbus-launch
Run Code Online (Sandbox Code Playgroud)
这将允许 SSH 会话关闭,但感觉很笨拙。有没有更好的解决方案?在不妨碍 dbus 的情况下运行远程 X11 应用程序的正确方法是什么?
小智 15
每个 dbus-launch(1):
如果未为尝试使用 D-Bus 的进程设置 DBUS_SESSION_BUS_ADDRESS,默认情况下,该进程将尝试使用 --autolaunch 选项调用 dbus-launch 以启动新的会话总线或在 X 显示器上查找现有的总线地址或在 ~/.dbus/session-bus/ 中的文件中
每当自动启动发生时,必须启动新总线的应用程序将处于自己的小世界中;如果它尝试使用大量总线服务,它最终可以有效地开始一个全新的会话。这可能是次优甚至完全破坏,具体取决于应用程序及其尝试执行的操作。
自动启动有两个常见原因。一个是到远程机器的 ssh。
所以看起来诀窍是抢先启动 dbus-daemon,这样程序就可以找到它。我用:
[me@host ~]$ dbus-launch --exit-with-session gnome-terminal
除了 gnome-terminal 之外,它还启动 dbus-daemon 并在 gnome-terminal 中设置 $DBUS_SESSION_BUS_ADDRESS 。
从 gnome-terminal 运行的任何 X 程序然后表现良好,当 gnome-terminal 退出时,dbus-launch 会自行清理。
我想知道问题是否不是由于未知或不存在的 dbus 会话引起的。
实际上,当 SSH 会话打开时,它不会启动 dbus 会话。某些程序可能会启动它,但会话不知道它(因此无法关闭它)。
不知道 dbus 会话也意味着程序使用 dbus 但不启动它自己会出现问题。
dbus 部分是每台机器和每台 X11 显示器。它们的信息存储在 $HOME/.dbus/session-bus/- 但是,那里引用的进程可能已关闭,因此需要额外检查以确定是否需要启动 dbus。然后,那里的变量将被导出到会话中。
然后它就像一个魅力:)
我将以下内容放入我的 .bash_profile 文件中:
# set dbus for remote SSH connections
if [ -n "$SSH_CLIENT" -a -n "$DISPLAY" ]; then
machine_id=$(LANGUAGE=C hostnamectl|grep 'Machine ID:'| sed 's/^.*: //')
x_display=$(echo $DISPLAY|sed 's/^.*:\([0-9]\+\)\(\.[0-9]\+\)*$/\1/')
dbus_session_file="$HOME/.dbus/session-bus/${machine_id}-${x_display}"
if [ -r "$dbus_session_file" ]; then
export $(grep '^DBUS.*=' "$dbus_session_file")
# check if PID still running, if not launch dbus
ps $DBUS_SESSION_BUS_PID | tail -1 | grep dbus-daemon >& /dev/null
[ "$?" != "0" ] && export $(dbus-launch) >& /dev/null
else
export $(dbus-launch) >& /dev/null
fi
fi
Run Code Online (Sandbox Code Playgroud)
注意:hostnamectl 是 systemd 的一部分,允许检索机器 ID dbus-launch 显示我们想要的变量;通过使用export $(dbus-launch)
我们检索 dbus-launch 的输出并导出变量
如果你希望它在非交互式 sessio 上完成(例如当从 ssh 运行命令时)尝试将它放在 .bashrc 中(但要注意 bashrc 在每个打开的 shell 中执行)