【问题标题】:Running notify-send as root以 root 身份运行通知发送
【发布时间】:2015-03-27 13:30:13
【问题描述】:

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

但是在尝试这个时:

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

我发现 gnome-panel 不存在。用谷歌搜索这个工作区,我发现很少有人抱怨这个工作区不再工作。所以我对该主题进行了一些研究并提出了这个(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

【问题讨论】:

标签: linux notifications root dbus notify


【解决方案1】:

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

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

【讨论】:

  • 谢谢。节省了我一些时间。最后一行类似的东西可以工作。在 Debian 9 上测试:su - $user -c "DISPLAY=$display DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus notify-send -i 'Title' 'Message'"
  • @ColinWa 函数的最后一行实际上是参数化的,看到那个“$@”了吗?它允许您将参数-i 'Title' 'Message' 直接传递给函数本身。它旨在用作真正的通知发送的直接替代品。
  • 我会更新第 6 行以包含 | head -n 1(使其成为 local user=$(who | grep '('$display')' | awk '{print $1} | head -n 1'))。我让它在我的机器上返回 8 个不同的用户 :)
【解决方案2】:

从以 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】:

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”'

【讨论】:

  • 在脚本中运行 notify-send 命令将不起作用,因为它将作为 sudo notify-send 执行,这是主要问题。我要试试这个服务名称,我会在几分钟内更新
  • 好吧,看来我真的不知道该怎么办,你能给我一些指示吗?而且我可以确认,当以 root 身份运行 notify-send 时,它不会显示任何想法,这就是我所说的工作的重点。
  • 用如何解决root 问题的建议更新答案。检查一下,如果有问题再回来。
  • 很高兴看到我没有那么迷茫,我已经试过这个了。现在我找到了这个人 unix.stackexchange.com/questions/116536/… ,以为他正在使用其他操作系统 我尝试了这个 export DISPLAY=":0" 但它也不起作用
【解决方案4】:

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

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

我在 Arch 安装上通过 exec startx 运行 i3。另一方面,我注意到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”进程,它的工作原理相同,但似乎总是由普通用户运行。

【讨论】:

    【解决方案5】:

    我也在研究这个以修复重启时背景损坏的错误。我想向 /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.*$')
    

    【讨论】:

      【解决方案6】:

      我最近在 notify-send 上苦苦挣扎并让它工作(在 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
      

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

      问候 达斯巴施迪

      【讨论】:

        【解决方案7】:
        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用户成功弹出通知栏

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-03
          • 2017-07-29
          • 2013-12-19
          • 2022-09-29
          • 2012-09-01
          • 1970-01-01
          相关资源
          最近更新 更多