You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Wayland环境下以root身份运行notify-send发送通知失败求助

Wayland环境下修复notify-send脚本的方案

你的脚本在Wayland环境下失效的核心问题有两个:

  1. WAYLAND_DISPLAY的格式是wayland-0这类字符串,你错误拼接成了:wayland-0,不符合Wayland的会话标识规则;
  2. who命令在Wayland环境下不会返回带(display)格式的条目,导致无法正确获取会话用户。

以下是修正后的脚本,同时兼容X11和Wayland环境:

#!/bin/bash

function notify-send() {
    # 检测当前会话类型
    local session_type="$XDG_SESSION_TYPE"
    
    local user=""
    local uid=""
    local dbus_addr=""
    local display=""

    if [ "$session_type" = "wayland" ]; then
        # Wayland环境:通过loginctl获取活跃会话的用户
        local session_id=$(loginctl list-sessions | grep -E 'active.*wayland' | awk '{print $1}')
        local user_id=$(loginctl show-session "$session_id" -p User --value)
        user=$(getent passwd "$user_id" | cut -d: -f1)
        uid=$(id -u "$user")
        dbus_addr="unix:path=/run/user/$uid/bus"
    else
        # X11环境:保留原有逻辑
        display=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)"
        user=$(who | grep "($display)" | awk '{print $1}' | head -n 1)
        uid=$(id -u "$user")
        dbus_addr="unix:path=/run/user/$uid/bus"
    fi

    # 验证用户存在后执行通知
    if [ -n "$user" ]; then
        sudo -u "$user" DBUS_SESSION_BUS_ADDRESS="$dbus_addr" DISPLAY="$display" notify-send "$@"
    else
        echo "无法定位当前会话用户" >&2
        return 1
    fi
}

notify-send "hi"

关键修改说明

  • Wayland会话用户检测:改用loginctl工具获取活跃会话信息,这是Wayland环境下可靠的会话管理方式,替代了X11环境下的who命令逻辑;
  • 移除错误的DISPLAY拼接:Wayland环境不需要设置DISPLAY变量,仅需确保正确的用户级DBUS总线地址;
  • 增加容错检查:添加用户存在性验证,避免空用户导致sudo执行失败;
  • 统一DBUS地址处理:X11和Wayland环境均使用/run/user/$uid/bus作为用户会话总线路径,这是Linux系统的标准配置。

额外注意事项

执行脚本的用户需要具备无需密码的sudo权限,可以通过visudo添加规则:

your_username ALL=(ALL) NOPASSWD: /usr/bin/notify-send

内容的提问来源于stack exchange,提问作者markoly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 01:15:34