在 tmux 会话中使用通知发送显示错误,没有通知

Ben*_*rds 2 linux terminal notifications tmux

我大量使用 tmux,并且有一些脚本使用 notify-send 为我提供屏幕通知。我发现了一个特殊情况,通知发送将失败,并且除了启动新的 tmux 会话(这显然不理想)之外,我还没有找到其他解决方法。

如果我创建一个新的 tmux 会话并使用通知发送,我会看到没有问题的通知弹出。但是一旦我从 tmux 会话中分离出来,然后稍后重新附加到它,notify-send 将失败并显示以下消息:

 $ notify-send test

(notify-send:26902): GLib-GObject-CRITICAL **: g_object_unref: assertion `G_IS_OBJECT (object)' failed
Run Code Online (Sandbox Code Playgroud)

除了将我的工作转移到新的 tmux 会话之外,我没有找到任何解决方案,这并不理想,因为这首先否定了使用 tmux 的全部意义。我不确定发生了什么。也许有某种 IPC 路径在终端和通知发送使用的 tmux 之间被破坏,或者其他什么?有什么办法可以在不丢失现有 tmux 会话的情况下恢复通知发送的功能?

use*_*686 5

虽然错误消息不是最理想的,但它似乎转换为“与 D-Bus 会话总线的连接不可用”。

notify-send 的工作原理是通过 D-Bus 发送 IPC 消息 - 特别是通过会话总线,其地址随每次 dbus-daemon 启动而随机分配并存储在$DBUS_SESSION_BUS_ADDRESS环境变量中。

通常它不是特定于当前终端——它一直从 X11 会话管理器继承,所以如果你同时启动两个终端,它们都将使用相同的会话总线。

但是如果你从 tmux 分离,重新启动你的 X11 会话,然后重新连接,新的会话将有一个新的总线,但里面的所有正在运行的进程仍然会有旧的环境。


部分解决方法是将此 envvar 添加到 tmux 的update-environment设置中:

set -g update-environment "DBUS_SESSION_BUS_ADDRESS DISPLAY SSH_AUTH_SOCK XAUTHORITY"
Run Code Online (Sandbox Code Playgroud)

请注意,这仅适用于该会话中的tmux 窗口;tmux 不可能更新现有shell的环境。


或者,让您的 X11 启动脚本将 DBUS_SESSION_BUS_ADDRESS 的值存储在某个文件中,并制作一个包装脚本,notify-send在运行真正的/usr/bin/notify-send.

这类似于 D-Bus“自动启动”的工作方式(或曾经工作)。如果$DISPLAY已设置但未设置$DBUS_SESSION_BUS_ADDRESS,则会话总线客户端将查找~/.dbus/当前显示器的总线地址。然而,由于各种原因,“自动启动”机制正在被弃用(它是片状的,它留下了垃圾,它让人们认为 D-Bus 需要 X11,等等)。


一些发行版正在转向“用户总线”模型,其中每个用户在固定位置(通常在)只有一个“会话”总线unix:path=/run/user/$UID/bus。这样,环境永远不会改变。(即使它根本没有,大多数 D-Bus 客户已经检查了该特定位置。)

在 Debian 上,可以通过安装来选择用户总线模型dbus-user-session——尽管它可能会破坏其他一些东西。