実行中のすべてのXモニターに通知を表示する

実行中のすべてのXモニターに通知を表示する

コマンドラインを使用して実行中のすべてのXモニターに通知を表示したいと思います。 (そしてコンソール実行)

それは次のとおりです。

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

これができるプログラムはありますか?そうでない場合は、bashを使用して実装できますか?

答え1

Command Wall を使用してすべてのコンソールにメッセージを送信できます。

X から通知を送信するには、通知の送信を使用して、現在のモニターの現在のユーザーに通知を送信できます。 (あなたの質問で判断すると、すでに知っているようです。)いくつかの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 セッションを実行する 2 人のユーザー、つまりモニター 0 の markmerk3 とモニター 1 の seamonkey があることがわかります。私の考えでは、tty [0-9] *をgrepし、行の末尾に(:[0 -9.] *)があることを確認してコンソールログインを削除してディスプレイIDを抽出する必要があると思います。括弧の間に文字列があります。

答え2

この投稿は少し古いです。申し訳ありません。しかし、このトピックに役立つものを追加できることを願っています。 (Josef Kufnerも素晴らしいスクリプトを書いていましたが、私には長すぎてPHPを使用しました。)

また、元の質問(すべてのアクティブなXユーザーにメッセージを送信する)で説明されているツールが必要です。ここにある回答に基づいてアクティブなXユーザーを検索し、who(を使用して)notify-send各アクティブユーザーに対して実行する小さなbash専用のスクリプトを作成しました。

最善の点は、すべてのパラメータで "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では、rootとして実行されているcrontabスクリプトから通知を受けたいと思います。環境変数を設定した後、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_ADDRESSCentos 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

関連情報