在所有正在运行的 X 显示器上显示通知

在所有正在运行的 X 显示器上显示通知

使用命令行,我想在每个正在运行的 X 显示器上显示通知。 (和运行控制台)

就像是:

notify-send-all 'Warning' 'Nuclear launch in 5 minutes, please evacuate'

有一个程序可以做到这一点吗?如果没有的话可以用bash实现吗?

答案1

您可以使用命令墙向所有控制台发送消息。

对于在 X 下发送通知,可以使用 notification-send 向当前显示器上的当前用户发送通知。 (从你的问题来看,我猜你已经知道这个了。)你可以使用一些 bash 脚本来构建这一点。基本上,您必须找出哪些用户在哪些 X-Display 上。获得此信息后,您可以像这样使用通知发送:

DISPLAY=:0 sudo -u fschmitt notify-send "Message"

其中 fschmitt 是显示 0 处的用户。您可以解析“who”命令的输出以查找所有用户及其显示。输出看起来像这样

[edinburgh:~]$ who
markmerk3 tty7         2010-09-23 10:59 (:0)
markmerk3 pts/1        2010-09-30 13:30 (:0.0)
fschmitt pts/2        2010-10-08 11:44 (ip-77-25-137-234.web.vodafone.de)
markmerk3 pts/0        2010-09-29 18:51 (:0.0)
seamonkey pts/6        2010-09-27 15:50 (:1.0)
markmerk3 pts/5        2010-09-27 14:04 (:0.0)
seamonkey tty8         2010-09-27 15:49 (:1)
markmerk3 pts/13       2010-09-28 17:23 (:0.0)
markmerk3 pts/3        2010-10-05 10:40 (:0.0)

您会看到,有两个用户正在运行 X 会话,markmerk3 在显示器 0 处,seamonkey 在显示器 1 处。我认为您需要 grep 查找 tty[0-9]* 然后确保在该行末尾有 (:[0 -9.]*) 摆脱控制台登录并从括号之间的字符串中提取显示 ID。

答案2

这个帖子有点旧了,抱歉,但我希望我仍然可以为这个主题添加一些有用的东西。 (Josef Kufner 还写了一个不错的脚本,只是对我来说有点太长了,而且它使用 PHP)。

我还需要一个如原始问题中所述的工具(向所有活跃的 X 用户发送消息)。根据这里的答案,我编写了这个仅 bash 的小脚本,它搜索活动的 X 用户(使用who),然后notify-send为每个活动用户运行。

最好的是:您可以像“notify-send”一样使用我的脚本及其所有参数! ;-)

通知发送全部:

#!/bin/bash
PATH=/usr/bin:/bin

XUSERS=($(who|grep -E "\(:[0-9](\.[0-9])*\)"|awk '{print $1$NF}'|sort -u))
for XUSER in "${XUSERS[@]}"; do
    NAME=(${XUSER/(/ })
    DISPLAY=${NAME[1]/)/}
    DBUS_ADDRESS=unix:path=/run/user/$(id -u ${NAME[0]})/bus
    sudo -u ${NAME[0]} DISPLAY=${DISPLAY} \
                       DBUS_SESSION_BUS_ADDRESS=${DBUS_ADDRESS} \
                       PATH=${PATH} \
                       notify-send "$@"
done

将上述代码复制到名为 的文件中notify-send-all,使其可执行并将其复制到/usr/local/bin或者/usr/bin(随你便)。然后在控制台会话中以 root 身份运行它,如下所示:

notify-send-all -t 10000 "Warning" "The hovercraft is full of eels!"

我已经在不同的机器上使用它几个月了,到目前为止没有任何问题,并且我已经使用 MATE 和 Cinnamon 桌面对其进行了测试。也在 cron 和 anacron 中成功运行它。

我为 Arch Linux 编写了这个脚本,所以如果您在其他 Linux 发行版或桌面上遇到问题,请告诉我。

答案3

在 Ubuntu 16.04 中,我希望从 crontab 以 root 身份运行的脚本获得通知。设置环境变量后,sudo -u $user由于某种原因不起作用,但sh -c "..." $user确实起作用了。

所以我现在使用这个功能:

notify_all() {
    local title=$1
    local msg=$2

    who | awk '{print $1, $NF}' | tr -d "()" |
    while read u d; do
        id=$(id -u $u)
        . /run/user/$id/dbus-session
        export DBUS_SESSION_BUS_ADDRESS
        export DISPLAY=$d
        su $u -c "/usr/bin/notify-send '$title' '$msg'"
    done 
}

如何查找 DBUS_SESSION_BUS_ADDRESS 变量可能取决于您的发行版。在 Ubuntu 16.04 中,它位于 中/run/user/$UID/dbus-session,可以简单地获取它。id -u在上面的函数中用于从 . 返回的用户名中获取 UID who

答案4

这是 Andy 脚本的更新:它确定的方式DBUS_SESSION_BUS_ADDRESS在 Centos 7 上不起作用。此外,该who命令由于某种原因没有列出某些会话,因此我ps aux改为解析输出。该脚本假设用户使用 X2GO ( ) 登录nxagent,但对于其他情况进行调整应该很简单。

#!/bin/bash
PATH=/usr/bin:/bin
NOTIFY_ARGS='-u critical "Shutdown notice" "THE SYSTEM IS GOING DOWN TODAY AT 23:00.\nWe recommend you to save your work in time\!" -i /usr/share/icons/Adwaita/32x32/devices/computer.png -t 28800000'

function extract_displays {
    local processes=$1
    processes=$(printf '%s\n' "$processes" | grep -P "nxagent.+:\d+")
    ids=$(printf '%s\n' "$processes" | grep -oP "\W\K:(\d)+")
    echo $ids
}


function find_dbus_address {
    local name=$1
    PID=$(pgrep 'mate-session' -u $name)
    if [ -z "$PID" ]; then
        PID=$(pgrep 'gnome-session' -u $name)
    fi
    if [ -z "$PID" ]; then
        PID=$(pgrep 'xfce4-session' -u $name)
    fi

    exp=$(cat /proc/$PID/environ | grep -z "^DBUS_SESSION_BUS_ADDRESS=")
    echo $exp
}

PROCESSES=$(ps aux)
DISPLAY_IDS=$(extract_displays "$PROCESSES")
echo "Found the following DISPLAYS: $DISPLAY_IDS"
for DISPLAY in $DISPLAY_IDS; do
    NAME=$(printf '%s\n' "$PROCESSES" | grep -P "nxagent.+$DISPLAY" | cut -f1 -d ' ')
    DBUS_ADDRESS=$(find_dbus_address $NAME)
    echo "Sending message to NAME=$NAME DISPLAY=$DISPLAY DBUS_ADDRESS=$DBUS_ADDRESS"
    echo "NOTIFY_ARGS=$NOTIFY_ARGS"
    eval sudo -u ${NAME} DISPLAY=${DISPLAY} ${DBUS_ADDRESS} PATH=${PATH} notify-send $NOTIFY_ARGS
done

相关内容