运行 以 root 身份通知发送

Running notify-send as root

我试图在插入 USB 设备时收到通知,为此我使用 udev 规则来跟踪它插入的时刻,并从那里启动脚本。 脚本的想法是使用 link.

中解释的内容

但是尝试这个时:

pids=`pgrep -u $user gnome-panel`

我发现没有 gnome-panel。在谷歌上搜索了这项工作,我发现很少有人抱怨这项工作不再有效。所以我对这个主题做了一些研究并想出了这个(通知-plugin2.sh):

#!/bin/bash

DBUS_SESSION_BUS_ADDRESS=$(cat /home/user/.dbus/session-bus/$(cat /var/lib/dbus/machine-id)-0 | grep DBUS_SESSION_BUS_ADDRESS= | sed -e 's/DBUS_SESSION_BUS_ADDRESS=//')

su user Test.sh $DBUS_SESSION_BUS_ADDRESS

在将用户切换到非 root 用户之前获取 DBUS_SESSION_BUS_ADDRESS。如果我没记错的话,这条语句是有效的,所以根据上面 link 中的代码,我制作了另一个脚本 (Test.sh)

#!/bin/sh
user=`whoami`
title="Test"
timeout=30000
icon="~/Pictures/PicturesForPwrPoint/Pluged.jpg"

DBUS_SESSION_BUS_ADDRESS=

echo $DBUS_SESSION_BUS_ADDRESS
DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS \ notify-send -u low -t $timeout -i "$icon" "$title"

对于我在其他代码上看到的,唯一的问题是获取 DBUS_SESSION_BUS_ADDRESS,如果我没记错的话,我可以得到它。

所以我的问题是,为什么启动时屏幕上没有花哨的弹出消息?

sudo sh notify-plugin2.sh

ubuntu 14.04 的通知服务已更改。

它现在被称为smth org.freedesktop.Notifications.service

您可以检查 here 以获取有关 Notification On Screen Display 可能性的更多信息。

您也可以使用以下命令行发送您自己的消息

user@machine ~$ notify-send “Text of message”

只需更新 udev 正在启动的脚本即可使用它。


要解决与运行以 root 身份执行 notify-send 命令相关的问题。

尝试运行作为您的普通用户,即

su <YOURUSER> -c 'notify-send “Text of message”'

我也在研究这个问题,以修复重启时背景损坏的错误。我想向 /etc/pm/sleep.d/ 添加一个脚本来重置它,但需要 DBUS_SESSION_BUS_ADDRESS 来设置它(gnome 桌面)。我发现 /home/user/.dbus/session-bus/* 文件中存储的 DBUS_SESSION_BUS_ADDRESS 与用户环境中的不匹配。但我确实发现在 dbus-daemon 命令之一中可用。

所以我能够通过下面的片段获得 DBUS_SESSION_BUS_ADDRESS 并且我能够成功地使用它。将“[用户名]”替换为您的用户。希望这有帮助。

$ export DBUS_SESSION_BUS_ADDRESS=$(pgrep -a dbus-daemon -U [username] | grep -o 'unix:abstract.*$')

我在 notify-send myself lateley 中苦苦挣扎并让它工作(在 Ubuntu 16.04 下)。

我觉得有2个方面。主叫用户必须有权访问显示消息,并且必须指定显示。

root@mymachine~# who
root     tty1         2017-06-19 16:30
<user1>  tty7         2017-06-20 07:15 (:0)
<user1>  pts/2        2017-06-20 07:42 (:0.0)
root     pts/14       2017-06-20 07:05 (<IP1>)
<user1>  pts/16       2017-06-20 07:15 (:0.0)
root     pts/17       2017-06-19 17:15 (<IP2>)
<user2>               2017-06-20 07:39 (<IP3>:2) #VNC
<user1>  pts/26       2017-06-19 18:03 (<IP3>:1.0) #VNC

所以对我有用的是

su - <user2> -c "DISPLAY=<IP3>:2 notify-send hi"

我认为通过切换到用户,您可以使用他们的 ~/.Xauthority。授权后,指定显示有效。

目前我是用另一种方式获取权限的。我遍历了每个登录用户的 ~/.Xauthority 文件并收集了他们的授权 cookie。之后使用正确的 DISPLAY-Variable 工作。我什至收集了显示管理器的 cookie(在我的例子中是 lightdm)

~/.Xauthority 文件(收集后):

root@mymaching:~# xauth list
<HOSTNAME3>:3  MIT-MAGIC-COOKIE-1  0ebdee59ee015f49066f372b00589420
<HOSTNAME3>:1  MIT-MAGIC-COOKIE-1  74254e326e8904419d005a05a6e95a8c
<HOSTNAME3>/unix:0  MIT-MAGIC-COOKIE-1  54d4cdb35eff20375e486f88e6ac8c74
<HOSTNAME3>:2  MIT-MAGIC-COOKIE-1  c6a07838c7456224799eedfff2be7cd5

到目前为止我的脚本(我想它还不是最终版本)

#!/bin/bash
users="$(who | awk '{print }' | sort -u | grep -v root)"
rm ~/.Xauthority
touch ~/.Xauthority
for user in $users; do
   xauth_file=/home/$user/.Xauthority
   while read cookie; do
      xauth add $cookie
   done <<< "$(xauth -f $xauth_file  list | grep $HOSTNAME)"
done
for xauth_file in $(find /var/run/lightdm -type f); do
   while read cookie; do
      xauth add $cookie
   done <<< "$(xauth -f $xauth_file  list | grep $HOSTNAME)"
done
for display in $(xauth list | awk '{print }' | cut -d/ -f2); do
   DISPLAY=$display notify-send "$@"
done

图例: <> 中的项目是匿名的。 IPX 匹配 HOSTNAMEX

您好 达斯巴施迪

以 root
身份从后台脚本 运行 发送桌面通知 (将 X_user 和 X_userid 分别替换为用户和用户 ID 运行 X):

sudo -u X_user DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/X_userid/bus notify-send 'Hello world!' 'This is an example notification.'

本文摘自: https://wiki.archlinux.org/index.php/Desktop_notifications

结合 with hongo's answer to another question 优雅地解决了我的问题。

function notify-send() {
    #Detect the name of the display in use
    local display=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)"

    #Detect the user using such display
    local user=$(who | grep '('$display')' | awk '{print }' | head -n 1)

    #Detect the id of the user
    local uid=$(id -u $user)

    sudo -u $user DISPLAY=$display DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus notify-send "$@"
}

该函数可以 as-is 在任何脚本 运行 中用作 root,作为 notify-send 命令的 drop-in 替换。

notify-send() 
{
    local display=$DISPLAY
    local user=$(who | grep '('$display')' | awk '{print }')
    local uid=$(id -u $user)
    sudo -u $user DISPLAY=$display DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus notify-send "$@"
}

在uos1022系统上,我可以通过环境变量$DISPLAY查询自己的window,从而以root用户成功弹出通知栏

我尝试了 的解决方案。但是,我注意到它在我的 Arch Linux 安装中并没有始终如一地工作。问题是 who 没有显示 tty1 会话的端口号:

$ who
john       tty1         2021-03-21 09:02

我在 Arch 安装上 运行ning i3 via exec startx。另一方面,我注意到 who 在 Ubuntu 桌面安装上的输出看起来完全不同。在这里,显示数量显示:

$ who
john       :0           2021-03-21 09:49 (:0)

所以我正在寻找另一种解决方案来摆脱 who 命令。我发现 ps aux 包含这个有用的条目,其中包含显示号码和用户名:

$ ps aux | grep xinit
john 785 763 0 19:14 tty1 S+ 0:00 xinit /home/john/.xinitrc -- /etc/X11/xinit/xserverrc :0 vt1 -keeptty -auth /tmp/serverauth.gGcqw2rJXG

这是我写的新脚本:

#/bin/bash

xinit_pid=$(pgrep xinit)

if [ -n "xinit_pid" ]; then
    xinit_ps=$(ps --no-headers -f $xinit_pid | head -n 1)
    display=$(echo "$xinit_ps" | grep -Po " :[0-9]+ " | tr -d " ")
    user=$(echo "$xinit_ps" | cut -d " " -f 1)
    uid=$(id -u $user)
    echo "Display environment: $display $user $uid"
    sudo -u $user DISPLAY=$display DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus notify-send "$@"
else
    echo "Warning: Could not find xinit process!"
fi

任何其他脚本都可以通过以下方式调用此脚本:

bash /opt/notify-send-helper Title Message -t 5000

旁注:我使用 dunstify 而不是 notify-senddunstify 的优点是能够为通知分配 ID:仅显示同一 ID 的最新通知。

编辑:我曾经查询进程“Xorg”。然而,奇怪的是我在一台机器上注意到这个进程是 运行 作为 root。我改用了“xinit”进程,它的工作原理是一样的,但普通用户似乎总是 运行。