以root身份运行notify-send

时间:2015-01-28 15:17:19

标签: linux notifications root dbus notify

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

但在尝试时:

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

我发现gnome-panel不存在。用Google搜索这项工作,我发现很少有人抱怨这项工作不再有效。所以我对这个主题进行了一些研究,并想出了这个(notify-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。这句话,如果我没有错,那么基于上面链接的代码我做了这个其他的脚本(Test.sh

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

DBUS_SESSION_BUS_ADDRESS=$1

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

7 个答案:

答案 0 :(得分:7)

tomy's answerhongo'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 $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 "$@"
}

该函数可以在任何运行为root的脚本中原样使用,作为notify-send命令的替代品。

答案 1 :(得分:5)

ubuntu 14.04已更改通知服务。

现在称为org.freedesktop.Notifications.service

您可以查看here,了解有关Notification On Screen Display种可能性的更多信息。

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

  

user @ machine~ $ notify-send“消息文本”

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


解决以root身份运行notify-send命令所遇到的问题。

尝试以正常用户身份运行,即

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

答案 2 :(得分:4)

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

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

答案 3 :(得分:0)

我也正在调查此问题以修复重启后损坏后台的错误。我想在/etc/pm/sleep.d/中添加一个脚本来重置它,但是需要DBUS_SESSION_BUS_ADDRESS来设置它(gnome桌面)。我发现/home/user/.dbus/session-bus/*文件中存储的DBUS_SESSION_BUS_ADDRESS与用户环境中的DBUS_SESSION_BUS_ADDRESS不匹配。但我确实在其中一个dbus-daemon命令中找到了一个。

所以我通过下面的剪辑获得了DBUS_SESSION_BUS_ADDRESS,我成功地使用了它。将“[username]”替换为您的用户。希望这会有所帮助。

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

答案 4 :(得分:0)

我努力与通知发送自己后来并使其工作(在Ubuntu 16.04下)。

我认为有两个方面。主叫用户必须能够访问显示屏,并且必须显示消息,并且必须指定显示。

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 $1}' | 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 $1}' | cut -d/ -f2); do
   DISPLAY=$display notify-send "$@"
done

注: &lt;&gt;中的项目是匿名的。 IPX匹配HOSTNAMEX

问候 dasBaschdi

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

我尝试了 Fabio A 的解决方案。但是,我注意到它在我的 Arch Linux 安装上并不一致。问题是 who 没有显示端口号:

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

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

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

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

$ ps aux | grep Xorg
me        804  1.1  0.5 1159752 95104 tty1    Sl   20:40   1:05 /usr/lib/Xorg -nolisten tcp :0 vt1 -keeptty -auth /tmp/serverauth.VgAC3ADl0t

这是我写的新脚本:

#/bin/bash

xorg_pid=$(pgrep Xorg)

if [ -n "xorg_pid" ]; then
    xorg_ps=$(ps --no-headers -f $xorg_pid | head -n 1)
    display=$(echo "$xorg_ps" | grep -Po " :[0-9]+ " | tr -d " ")
    user=$(echo "$xorg_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 Xorg process!"
fi

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

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

附带说明:我使用的是 dunstify 而不是 notify-senddunstify 的优势在于能够为通知分配 ID。仅显示相同 ID 的最新通知。