Show a notification across all running X displays











up vote
14
down vote

favorite
5












Using the command line, I'd like show a notification on every running X display. ( and running console )



Something like:



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


Is there a program that will do this? If not, can this be implemented with bash?










share|improve this question




















  • 1




    For people coming here years later, there is a simple notify_all function in this answer which works in Ubuntu 16.04, and can be used in scripts started by root.
    – mivk
    Feb 12 '17 at 11:48















up vote
14
down vote

favorite
5












Using the command line, I'd like show a notification on every running X display. ( and running console )



Something like:



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


Is there a program that will do this? If not, can this be implemented with bash?










share|improve this question




















  • 1




    For people coming here years later, there is a simple notify_all function in this answer which works in Ubuntu 16.04, and can be used in scripts started by root.
    – mivk
    Feb 12 '17 at 11:48













up vote
14
down vote

favorite
5









up vote
14
down vote

favorite
5






5





Using the command line, I'd like show a notification on every running X display. ( and running console )



Something like:



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


Is there a program that will do this? If not, can this be implemented with bash?










share|improve this question















Using the command line, I'd like show a notification on every running X display. ( and running console )



Something like:



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


Is there a program that will do this? If not, can this be implemented with bash?







command-line xorg tty console notifications






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Apr 25 '11 at 17:00









Caleb

50.2k9146190




50.2k9146190










asked Oct 8 '10 at 8:17









Stefan

11.5k3182123




11.5k3182123








  • 1




    For people coming here years later, there is a simple notify_all function in this answer which works in Ubuntu 16.04, and can be used in scripts started by root.
    – mivk
    Feb 12 '17 at 11:48














  • 1




    For people coming here years later, there is a simple notify_all function in this answer which works in Ubuntu 16.04, and can be used in scripts started by root.
    – mivk
    Feb 12 '17 at 11:48








1




1




For people coming here years later, there is a simple notify_all function in this answer which works in Ubuntu 16.04, and can be used in scripts started by root.
– mivk
Feb 12 '17 at 11:48




For people coming here years later, there is a simple notify_all function in this answer which works in Ubuntu 16.04, and can be used in scripts started by root.
– mivk
Feb 12 '17 at 11:48










6 Answers
6






active

oldest

votes

















up vote
14
down vote



accepted










You can send a message to all consoles with the command wall.



For sending notifications under X there is notify-send which sends a notification to the current user on the current display. (From your question, I guess you already know this one.) You can build upon this with some bash scripting. Basically you have to find out which users are on which X-Displays. Once you got this info you can use notify-send like this:



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


Where fschmitt is the user at display 0. You can parse the output of the "who" command to find all users and their displays. The output looks like this



[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)


You see, there are two users running X sessions, markmerk3 at display 0 and seamonkey at display 1. I think you need to grep for tty[0-9]* then assure that at the end of the line there is (:[0-9.]*) to get rid of console logins and extract the display id from the string between the parentheses.






share|improve this answer



















  • 2




    The command who tells you who is logged in and on which X display that login is. You just might have to filter it somewhat.
    – tante
    Oct 8 '10 at 9:49






  • 1




    While it is probably better to just use a loop in a shell script you could always do something like who | awk '/(:[0-9]+)/ {gsub("[:|(|)]","");print "DISPLAY=:"$5 " sudo -u " $1 " notify-send "Message""}' | bash. Also, you might want to see unix.stackexchange.com/questions/1596/…
    – Steven D
    Oct 8 '10 at 15:34


















up vote
5
down vote













This thread is a bit old, sorry, but I hope I still can add something useful to the topic. (also Josef Kufner wrote a nice script, it was just a little bit too long for my taste, and it uses PHP)



I also needed a tool as described in the original question (to send a message to all active X-users). And based on the answers here, I wrote this little bash-only script, which searches for active X-users (using 'who'), and then running notify-send for every active user.



And the best: you can use my script exactly like "notify-send", with all of its parameters! ;-)



notify-send-all:



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

XUSERS=($(who|grep -E "(:[0-9](.[0-9])*)"|awk '{print $1$5}'|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


Copy the above code into a file named "notify-send-all", make it executable and copy it to /usr/local/bin or /usr/bin (as you like).
Then run it e.g. as root in a console session like this:



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



I'm using it several months now, on different machines, and didn't have any problems so far, and I've tested it with MATE and Cinnamon desktops.
Also successfully running it within cron and anacron.



I wrote this script for/under ArchLinux, so please tell me if you're having problems on another Linux distributions or desktops.






share|improve this answer























  • |egrep ?? is egrep a command ?
    – Sw0ut
    Apr 21 '17 at 9:06










  • @Sw0ut, egrep is indeed a command. But in the man page of grep(1) says that egrep, fgrep and rgrep are deprecated, and the use of their equivalent forms "grep -E", "grep -F" and "grep -r" is recommended.
    – rsuarez
    May 21 '17 at 16:49










  • Instead of awk '{print $1$5}' it is better to use awk '{print $1$NF}', so that it doesn't break on some locales where date is formatted with spaces (e.g. Jun 3 instead of 2017-06-03). Here is also a version to notify specific user instead of all users: gist.github.com/shvchk/ba2f0da49bf2f571d6bf606d96f289d7
    – Shevchuk
    Jun 3 '17 at 19:11










  • Works splendidly on Ubuntu after using grep -E and adding /bin to the path (see the edit). Feel free to revert if you object
    – serv-inc
    Oct 18 at 8:14




















up vote
3
down vote













I needed this too for some system-wide notifications. Here is my solution. It scans /proc to find all session busses and then it executes notify-send on each of it (once per bus). All arguments are passed unchanged to real notify-send.



#!/bin/bash

/bin/grep -sozZe '^DBUS_SESSION_BUS_ADDRESS=[a-zA-Z0-9:=,/-]*$' /proc/*/environ
| /usr/bin/php -r '
$busses = array();
array_shift($argv);
while($ln = fgets(STDIN)) {
list($f, $env) = explode("", $ln, 2);
if (file_exists($f)) {
$user = fileowner($f);
$busses[$user][trim($env)] = true;
}
}
foreach ($busses as $user => $user_busses) {
foreach ($user_busses as $env => $true) {
if (pcntl_fork()) {
posix_seteuid($user);
$env_array = array("DBUS_SESSION_BUS_ADDRESS" => preg_replace("/^DBUS_SESSION_BUS_ADDRESS=/", "", $env));
pcntl_exec("/usr/bin/notify-send", $argv, $env_array);
}
}
}
' -- "$@"





share|improve this answer




























    up vote
    1
    down vote













    In Ubuntu 16.04, I wanted notifications from a script running as root from crontab. After setting the environment variables, sudo -u $user didn't work for some reason, but sh -c "..." $user does work.



    So I now use this function:



    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
    }


    How to find the DBUS_SESSION_BUS_ADDRESS variable probably depends on your distribution. In Ubuntu 16.04, it is in /run/user/$UID/dbus-session, which can simply be sourced. id -u is used in the function above to get the UID from the username returned by who.






    share|improve this answer























    • How to use it? Can you help me?
      – elgolondrino
      Apr 1 '17 at 17:09


















    up vote
    0
    down vote













    Here's an update of Andy's script: The way it determined the DBUS_SESSION_BUS_ADDRESS does not work on Centos 7. Also the who command did not list some sessions for some reason, so I parse the ps aux output instead. This script assumes users are logged in using X2GO (nxagent), but it should be simple to adjust for other cases.



    #!/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 '%sn' "$processes" | grep -P "nxagent.+:d+")
    ids=$(printf '%sn' "$processes" | grep -oP "WK:(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 '%sn' "$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





    share|improve this answer








    New contributor




    jpf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.

























      up vote
      -1
      down vote













      users=$(who | awk '{print $1}')

      for user in $users<br>
      do
      DISPLAY=:0 sudo -u $user notify-send "hello!!"
      done





      share|improve this answer























        Your Answer








        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "106"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        convertImagesToLinks: false,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f2881%2fshow-a-notification-across-all-running-x-displays%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        6 Answers
        6






        active

        oldest

        votes








        6 Answers
        6






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes








        up vote
        14
        down vote



        accepted










        You can send a message to all consoles with the command wall.



        For sending notifications under X there is notify-send which sends a notification to the current user on the current display. (From your question, I guess you already know this one.) You can build upon this with some bash scripting. Basically you have to find out which users are on which X-Displays. Once you got this info you can use notify-send like this:



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


        Where fschmitt is the user at display 0. You can parse the output of the "who" command to find all users and their displays. The output looks like this



        [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)


        You see, there are two users running X sessions, markmerk3 at display 0 and seamonkey at display 1. I think you need to grep for tty[0-9]* then assure that at the end of the line there is (:[0-9.]*) to get rid of console logins and extract the display id from the string between the parentheses.






        share|improve this answer



















        • 2




          The command who tells you who is logged in and on which X display that login is. You just might have to filter it somewhat.
          – tante
          Oct 8 '10 at 9:49






        • 1




          While it is probably better to just use a loop in a shell script you could always do something like who | awk '/(:[0-9]+)/ {gsub("[:|(|)]","");print "DISPLAY=:"$5 " sudo -u " $1 " notify-send "Message""}' | bash. Also, you might want to see unix.stackexchange.com/questions/1596/…
          – Steven D
          Oct 8 '10 at 15:34















        up vote
        14
        down vote



        accepted










        You can send a message to all consoles with the command wall.



        For sending notifications under X there is notify-send which sends a notification to the current user on the current display. (From your question, I guess you already know this one.) You can build upon this with some bash scripting. Basically you have to find out which users are on which X-Displays. Once you got this info you can use notify-send like this:



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


        Where fschmitt is the user at display 0. You can parse the output of the "who" command to find all users and their displays. The output looks like this



        [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)


        You see, there are two users running X sessions, markmerk3 at display 0 and seamonkey at display 1. I think you need to grep for tty[0-9]* then assure that at the end of the line there is (:[0-9.]*) to get rid of console logins and extract the display id from the string between the parentheses.






        share|improve this answer



















        • 2




          The command who tells you who is logged in and on which X display that login is. You just might have to filter it somewhat.
          – tante
          Oct 8 '10 at 9:49






        • 1




          While it is probably better to just use a loop in a shell script you could always do something like who | awk '/(:[0-9]+)/ {gsub("[:|(|)]","");print "DISPLAY=:"$5 " sudo -u " $1 " notify-send "Message""}' | bash. Also, you might want to see unix.stackexchange.com/questions/1596/…
          – Steven D
          Oct 8 '10 at 15:34













        up vote
        14
        down vote



        accepted







        up vote
        14
        down vote



        accepted






        You can send a message to all consoles with the command wall.



        For sending notifications under X there is notify-send which sends a notification to the current user on the current display. (From your question, I guess you already know this one.) You can build upon this with some bash scripting. Basically you have to find out which users are on which X-Displays. Once you got this info you can use notify-send like this:



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


        Where fschmitt is the user at display 0. You can parse the output of the "who" command to find all users and their displays. The output looks like this



        [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)


        You see, there are two users running X sessions, markmerk3 at display 0 and seamonkey at display 1. I think you need to grep for tty[0-9]* then assure that at the end of the line there is (:[0-9.]*) to get rid of console logins and extract the display id from the string between the parentheses.






        share|improve this answer














        You can send a message to all consoles with the command wall.



        For sending notifications under X there is notify-send which sends a notification to the current user on the current display. (From your question, I guess you already know this one.) You can build upon this with some bash scripting. Basically you have to find out which users are on which X-Displays. Once you got this info you can use notify-send like this:



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


        Where fschmitt is the user at display 0. You can parse the output of the "who" command to find all users and their displays. The output looks like this



        [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)


        You see, there are two users running X sessions, markmerk3 at display 0 and seamonkey at display 1. I think you need to grep for tty[0-9]* then assure that at the end of the line there is (:[0-9.]*) to get rid of console logins and extract the display id from the string between the parentheses.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Oct 8 '10 at 11:08

























        answered Oct 8 '10 at 9:42









        fschmitt

        7,5713042




        7,5713042








        • 2




          The command who tells you who is logged in and on which X display that login is. You just might have to filter it somewhat.
          – tante
          Oct 8 '10 at 9:49






        • 1




          While it is probably better to just use a loop in a shell script you could always do something like who | awk '/(:[0-9]+)/ {gsub("[:|(|)]","");print "DISPLAY=:"$5 " sudo -u " $1 " notify-send "Message""}' | bash. Also, you might want to see unix.stackexchange.com/questions/1596/…
          – Steven D
          Oct 8 '10 at 15:34














        • 2




          The command who tells you who is logged in and on which X display that login is. You just might have to filter it somewhat.
          – tante
          Oct 8 '10 at 9:49






        • 1




          While it is probably better to just use a loop in a shell script you could always do something like who | awk '/(:[0-9]+)/ {gsub("[:|(|)]","");print "DISPLAY=:"$5 " sudo -u " $1 " notify-send "Message""}' | bash. Also, you might want to see unix.stackexchange.com/questions/1596/…
          – Steven D
          Oct 8 '10 at 15:34








        2




        2




        The command who tells you who is logged in and on which X display that login is. You just might have to filter it somewhat.
        – tante
        Oct 8 '10 at 9:49




        The command who tells you who is logged in and on which X display that login is. You just might have to filter it somewhat.
        – tante
        Oct 8 '10 at 9:49




        1




        1




        While it is probably better to just use a loop in a shell script you could always do something like who | awk '/(:[0-9]+)/ {gsub("[:|(|)]","");print "DISPLAY=:"$5 " sudo -u " $1 " notify-send "Message""}' | bash. Also, you might want to see unix.stackexchange.com/questions/1596/…
        – Steven D
        Oct 8 '10 at 15:34




        While it is probably better to just use a loop in a shell script you could always do something like who | awk '/(:[0-9]+)/ {gsub("[:|(|)]","");print "DISPLAY=:"$5 " sudo -u " $1 " notify-send "Message""}' | bash. Also, you might want to see unix.stackexchange.com/questions/1596/…
        – Steven D
        Oct 8 '10 at 15:34












        up vote
        5
        down vote













        This thread is a bit old, sorry, but I hope I still can add something useful to the topic. (also Josef Kufner wrote a nice script, it was just a little bit too long for my taste, and it uses PHP)



        I also needed a tool as described in the original question (to send a message to all active X-users). And based on the answers here, I wrote this little bash-only script, which searches for active X-users (using 'who'), and then running notify-send for every active user.



        And the best: you can use my script exactly like "notify-send", with all of its parameters! ;-)



        notify-send-all:



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

        XUSERS=($(who|grep -E "(:[0-9](.[0-9])*)"|awk '{print $1$5}'|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


        Copy the above code into a file named "notify-send-all", make it executable and copy it to /usr/local/bin or /usr/bin (as you like).
        Then run it e.g. as root in a console session like this:



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



        I'm using it several months now, on different machines, and didn't have any problems so far, and I've tested it with MATE and Cinnamon desktops.
        Also successfully running it within cron and anacron.



        I wrote this script for/under ArchLinux, so please tell me if you're having problems on another Linux distributions or desktops.






        share|improve this answer























        • |egrep ?? is egrep a command ?
          – Sw0ut
          Apr 21 '17 at 9:06










        • @Sw0ut, egrep is indeed a command. But in the man page of grep(1) says that egrep, fgrep and rgrep are deprecated, and the use of their equivalent forms "grep -E", "grep -F" and "grep -r" is recommended.
          – rsuarez
          May 21 '17 at 16:49










        • Instead of awk '{print $1$5}' it is better to use awk '{print $1$NF}', so that it doesn't break on some locales where date is formatted with spaces (e.g. Jun 3 instead of 2017-06-03). Here is also a version to notify specific user instead of all users: gist.github.com/shvchk/ba2f0da49bf2f571d6bf606d96f289d7
          – Shevchuk
          Jun 3 '17 at 19:11










        • Works splendidly on Ubuntu after using grep -E and adding /bin to the path (see the edit). Feel free to revert if you object
          – serv-inc
          Oct 18 at 8:14

















        up vote
        5
        down vote













        This thread is a bit old, sorry, but I hope I still can add something useful to the topic. (also Josef Kufner wrote a nice script, it was just a little bit too long for my taste, and it uses PHP)



        I also needed a tool as described in the original question (to send a message to all active X-users). And based on the answers here, I wrote this little bash-only script, which searches for active X-users (using 'who'), and then running notify-send for every active user.



        And the best: you can use my script exactly like "notify-send", with all of its parameters! ;-)



        notify-send-all:



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

        XUSERS=($(who|grep -E "(:[0-9](.[0-9])*)"|awk '{print $1$5}'|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


        Copy the above code into a file named "notify-send-all", make it executable and copy it to /usr/local/bin or /usr/bin (as you like).
        Then run it e.g. as root in a console session like this:



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



        I'm using it several months now, on different machines, and didn't have any problems so far, and I've tested it with MATE and Cinnamon desktops.
        Also successfully running it within cron and anacron.



        I wrote this script for/under ArchLinux, so please tell me if you're having problems on another Linux distributions or desktops.






        share|improve this answer























        • |egrep ?? is egrep a command ?
          – Sw0ut
          Apr 21 '17 at 9:06










        • @Sw0ut, egrep is indeed a command. But in the man page of grep(1) says that egrep, fgrep and rgrep are deprecated, and the use of their equivalent forms "grep -E", "grep -F" and "grep -r" is recommended.
          – rsuarez
          May 21 '17 at 16:49










        • Instead of awk '{print $1$5}' it is better to use awk '{print $1$NF}', so that it doesn't break on some locales where date is formatted with spaces (e.g. Jun 3 instead of 2017-06-03). Here is also a version to notify specific user instead of all users: gist.github.com/shvchk/ba2f0da49bf2f571d6bf606d96f289d7
          – Shevchuk
          Jun 3 '17 at 19:11










        • Works splendidly on Ubuntu after using grep -E and adding /bin to the path (see the edit). Feel free to revert if you object
          – serv-inc
          Oct 18 at 8:14















        up vote
        5
        down vote










        up vote
        5
        down vote









        This thread is a bit old, sorry, but I hope I still can add something useful to the topic. (also Josef Kufner wrote a nice script, it was just a little bit too long for my taste, and it uses PHP)



        I also needed a tool as described in the original question (to send a message to all active X-users). And based on the answers here, I wrote this little bash-only script, which searches for active X-users (using 'who'), and then running notify-send for every active user.



        And the best: you can use my script exactly like "notify-send", with all of its parameters! ;-)



        notify-send-all:



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

        XUSERS=($(who|grep -E "(:[0-9](.[0-9])*)"|awk '{print $1$5}'|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


        Copy the above code into a file named "notify-send-all", make it executable and copy it to /usr/local/bin or /usr/bin (as you like).
        Then run it e.g. as root in a console session like this:



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



        I'm using it several months now, on different machines, and didn't have any problems so far, and I've tested it with MATE and Cinnamon desktops.
        Also successfully running it within cron and anacron.



        I wrote this script for/under ArchLinux, so please tell me if you're having problems on another Linux distributions or desktops.






        share|improve this answer














        This thread is a bit old, sorry, but I hope I still can add something useful to the topic. (also Josef Kufner wrote a nice script, it was just a little bit too long for my taste, and it uses PHP)



        I also needed a tool as described in the original question (to send a message to all active X-users). And based on the answers here, I wrote this little bash-only script, which searches for active X-users (using 'who'), and then running notify-send for every active user.



        And the best: you can use my script exactly like "notify-send", with all of its parameters! ;-)



        notify-send-all:



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

        XUSERS=($(who|grep -E "(:[0-9](.[0-9])*)"|awk '{print $1$5}'|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


        Copy the above code into a file named "notify-send-all", make it executable and copy it to /usr/local/bin or /usr/bin (as you like).
        Then run it e.g. as root in a console session like this:



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



        I'm using it several months now, on different machines, and didn't have any problems so far, and I've tested it with MATE and Cinnamon desktops.
        Also successfully running it within cron and anacron.



        I wrote this script for/under ArchLinux, so please tell me if you're having problems on another Linux distributions or desktops.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Oct 18 at 8:44









        serv-inc

        436212




        436212










        answered Aug 31 '16 at 23:36









        Andy

        5112




        5112












        • |egrep ?? is egrep a command ?
          – Sw0ut
          Apr 21 '17 at 9:06










        • @Sw0ut, egrep is indeed a command. But in the man page of grep(1) says that egrep, fgrep and rgrep are deprecated, and the use of their equivalent forms "grep -E", "grep -F" and "grep -r" is recommended.
          – rsuarez
          May 21 '17 at 16:49










        • Instead of awk '{print $1$5}' it is better to use awk '{print $1$NF}', so that it doesn't break on some locales where date is formatted with spaces (e.g. Jun 3 instead of 2017-06-03). Here is also a version to notify specific user instead of all users: gist.github.com/shvchk/ba2f0da49bf2f571d6bf606d96f289d7
          – Shevchuk
          Jun 3 '17 at 19:11










        • Works splendidly on Ubuntu after using grep -E and adding /bin to the path (see the edit). Feel free to revert if you object
          – serv-inc
          Oct 18 at 8:14




















        • |egrep ?? is egrep a command ?
          – Sw0ut
          Apr 21 '17 at 9:06










        • @Sw0ut, egrep is indeed a command. But in the man page of grep(1) says that egrep, fgrep and rgrep are deprecated, and the use of their equivalent forms "grep -E", "grep -F" and "grep -r" is recommended.
          – rsuarez
          May 21 '17 at 16:49










        • Instead of awk '{print $1$5}' it is better to use awk '{print $1$NF}', so that it doesn't break on some locales where date is formatted with spaces (e.g. Jun 3 instead of 2017-06-03). Here is also a version to notify specific user instead of all users: gist.github.com/shvchk/ba2f0da49bf2f571d6bf606d96f289d7
          – Shevchuk
          Jun 3 '17 at 19:11










        • Works splendidly on Ubuntu after using grep -E and adding /bin to the path (see the edit). Feel free to revert if you object
          – serv-inc
          Oct 18 at 8:14


















        |egrep ?? is egrep a command ?
        – Sw0ut
        Apr 21 '17 at 9:06




        |egrep ?? is egrep a command ?
        – Sw0ut
        Apr 21 '17 at 9:06












        @Sw0ut, egrep is indeed a command. But in the man page of grep(1) says that egrep, fgrep and rgrep are deprecated, and the use of their equivalent forms "grep -E", "grep -F" and "grep -r" is recommended.
        – rsuarez
        May 21 '17 at 16:49




        @Sw0ut, egrep is indeed a command. But in the man page of grep(1) says that egrep, fgrep and rgrep are deprecated, and the use of their equivalent forms "grep -E", "grep -F" and "grep -r" is recommended.
        – rsuarez
        May 21 '17 at 16:49












        Instead of awk '{print $1$5}' it is better to use awk '{print $1$NF}', so that it doesn't break on some locales where date is formatted with spaces (e.g. Jun 3 instead of 2017-06-03). Here is also a version to notify specific user instead of all users: gist.github.com/shvchk/ba2f0da49bf2f571d6bf606d96f289d7
        – Shevchuk
        Jun 3 '17 at 19:11




        Instead of awk '{print $1$5}' it is better to use awk '{print $1$NF}', so that it doesn't break on some locales where date is formatted with spaces (e.g. Jun 3 instead of 2017-06-03). Here is also a version to notify specific user instead of all users: gist.github.com/shvchk/ba2f0da49bf2f571d6bf606d96f289d7
        – Shevchuk
        Jun 3 '17 at 19:11












        Works splendidly on Ubuntu after using grep -E and adding /bin to the path (see the edit). Feel free to revert if you object
        – serv-inc
        Oct 18 at 8:14






        Works splendidly on Ubuntu after using grep -E and adding /bin to the path (see the edit). Feel free to revert if you object
        – serv-inc
        Oct 18 at 8:14












        up vote
        3
        down vote













        I needed this too for some system-wide notifications. Here is my solution. It scans /proc to find all session busses and then it executes notify-send on each of it (once per bus). All arguments are passed unchanged to real notify-send.



        #!/bin/bash

        /bin/grep -sozZe '^DBUS_SESSION_BUS_ADDRESS=[a-zA-Z0-9:=,/-]*$' /proc/*/environ
        | /usr/bin/php -r '
        $busses = array();
        array_shift($argv);
        while($ln = fgets(STDIN)) {
        list($f, $env) = explode("", $ln, 2);
        if (file_exists($f)) {
        $user = fileowner($f);
        $busses[$user][trim($env)] = true;
        }
        }
        foreach ($busses as $user => $user_busses) {
        foreach ($user_busses as $env => $true) {
        if (pcntl_fork()) {
        posix_seteuid($user);
        $env_array = array("DBUS_SESSION_BUS_ADDRESS" => preg_replace("/^DBUS_SESSION_BUS_ADDRESS=/", "", $env));
        pcntl_exec("/usr/bin/notify-send", $argv, $env_array);
        }
        }
        }
        ' -- "$@"





        share|improve this answer

























          up vote
          3
          down vote













          I needed this too for some system-wide notifications. Here is my solution. It scans /proc to find all session busses and then it executes notify-send on each of it (once per bus). All arguments are passed unchanged to real notify-send.



          #!/bin/bash

          /bin/grep -sozZe '^DBUS_SESSION_BUS_ADDRESS=[a-zA-Z0-9:=,/-]*$' /proc/*/environ
          | /usr/bin/php -r '
          $busses = array();
          array_shift($argv);
          while($ln = fgets(STDIN)) {
          list($f, $env) = explode("", $ln, 2);
          if (file_exists($f)) {
          $user = fileowner($f);
          $busses[$user][trim($env)] = true;
          }
          }
          foreach ($busses as $user => $user_busses) {
          foreach ($user_busses as $env => $true) {
          if (pcntl_fork()) {
          posix_seteuid($user);
          $env_array = array("DBUS_SESSION_BUS_ADDRESS" => preg_replace("/^DBUS_SESSION_BUS_ADDRESS=/", "", $env));
          pcntl_exec("/usr/bin/notify-send", $argv, $env_array);
          }
          }
          }
          ' -- "$@"





          share|improve this answer























            up vote
            3
            down vote










            up vote
            3
            down vote









            I needed this too for some system-wide notifications. Here is my solution. It scans /proc to find all session busses and then it executes notify-send on each of it (once per bus). All arguments are passed unchanged to real notify-send.



            #!/bin/bash

            /bin/grep -sozZe '^DBUS_SESSION_BUS_ADDRESS=[a-zA-Z0-9:=,/-]*$' /proc/*/environ
            | /usr/bin/php -r '
            $busses = array();
            array_shift($argv);
            while($ln = fgets(STDIN)) {
            list($f, $env) = explode("", $ln, 2);
            if (file_exists($f)) {
            $user = fileowner($f);
            $busses[$user][trim($env)] = true;
            }
            }
            foreach ($busses as $user => $user_busses) {
            foreach ($user_busses as $env => $true) {
            if (pcntl_fork()) {
            posix_seteuid($user);
            $env_array = array("DBUS_SESSION_BUS_ADDRESS" => preg_replace("/^DBUS_SESSION_BUS_ADDRESS=/", "", $env));
            pcntl_exec("/usr/bin/notify-send", $argv, $env_array);
            }
            }
            }
            ' -- "$@"





            share|improve this answer












            I needed this too for some system-wide notifications. Here is my solution. It scans /proc to find all session busses and then it executes notify-send on each of it (once per bus). All arguments are passed unchanged to real notify-send.



            #!/bin/bash

            /bin/grep -sozZe '^DBUS_SESSION_BUS_ADDRESS=[a-zA-Z0-9:=,/-]*$' /proc/*/environ
            | /usr/bin/php -r '
            $busses = array();
            array_shift($argv);
            while($ln = fgets(STDIN)) {
            list($f, $env) = explode("", $ln, 2);
            if (file_exists($f)) {
            $user = fileowner($f);
            $busses[$user][trim($env)] = true;
            }
            }
            foreach ($busses as $user => $user_busses) {
            foreach ($user_busses as $env => $true) {
            if (pcntl_fork()) {
            posix_seteuid($user);
            $env_array = array("DBUS_SESSION_BUS_ADDRESS" => preg_replace("/^DBUS_SESSION_BUS_ADDRESS=/", "", $env));
            pcntl_exec("/usr/bin/notify-send", $argv, $env_array);
            }
            }
            }
            ' -- "$@"






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Sep 16 '15 at 14:06









            Josef Kufner

            1312




            1312






















                up vote
                1
                down vote













                In Ubuntu 16.04, I wanted notifications from a script running as root from crontab. After setting the environment variables, sudo -u $user didn't work for some reason, but sh -c "..." $user does work.



                So I now use this function:



                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
                }


                How to find the DBUS_SESSION_BUS_ADDRESS variable probably depends on your distribution. In Ubuntu 16.04, it is in /run/user/$UID/dbus-session, which can simply be sourced. id -u is used in the function above to get the UID from the username returned by who.






                share|improve this answer























                • How to use it? Can you help me?
                  – elgolondrino
                  Apr 1 '17 at 17:09















                up vote
                1
                down vote













                In Ubuntu 16.04, I wanted notifications from a script running as root from crontab. After setting the environment variables, sudo -u $user didn't work for some reason, but sh -c "..." $user does work.



                So I now use this function:



                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
                }


                How to find the DBUS_SESSION_BUS_ADDRESS variable probably depends on your distribution. In Ubuntu 16.04, it is in /run/user/$UID/dbus-session, which can simply be sourced. id -u is used in the function above to get the UID from the username returned by who.






                share|improve this answer























                • How to use it? Can you help me?
                  – elgolondrino
                  Apr 1 '17 at 17:09













                up vote
                1
                down vote










                up vote
                1
                down vote









                In Ubuntu 16.04, I wanted notifications from a script running as root from crontab. After setting the environment variables, sudo -u $user didn't work for some reason, but sh -c "..." $user does work.



                So I now use this function:



                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
                }


                How to find the DBUS_SESSION_BUS_ADDRESS variable probably depends on your distribution. In Ubuntu 16.04, it is in /run/user/$UID/dbus-session, which can simply be sourced. id -u is used in the function above to get the UID from the username returned by who.






                share|improve this answer














                In Ubuntu 16.04, I wanted notifications from a script running as root from crontab. After setting the environment variables, sudo -u $user didn't work for some reason, but sh -c "..." $user does work.



                So I now use this function:



                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
                }


                How to find the DBUS_SESSION_BUS_ADDRESS variable probably depends on your distribution. In Ubuntu 16.04, it is in /run/user/$UID/dbus-session, which can simply be sourced. id -u is used in the function above to get the UID from the username returned by who.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Feb 12 '17 at 10:31

























                answered Feb 12 '17 at 10:16









                mivk

                1,4841415




                1,4841415












                • How to use it? Can you help me?
                  – elgolondrino
                  Apr 1 '17 at 17:09


















                • How to use it? Can you help me?
                  – elgolondrino
                  Apr 1 '17 at 17:09
















                How to use it? Can you help me?
                – elgolondrino
                Apr 1 '17 at 17:09




                How to use it? Can you help me?
                – elgolondrino
                Apr 1 '17 at 17:09










                up vote
                0
                down vote













                Here's an update of Andy's script: The way it determined the DBUS_SESSION_BUS_ADDRESS does not work on Centos 7. Also the who command did not list some sessions for some reason, so I parse the ps aux output instead. This script assumes users are logged in using X2GO (nxagent), but it should be simple to adjust for other cases.



                #!/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 '%sn' "$processes" | grep -P "nxagent.+:d+")
                ids=$(printf '%sn' "$processes" | grep -oP "WK:(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 '%sn' "$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





                share|improve this answer








                New contributor




                jpf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.






















                  up vote
                  0
                  down vote













                  Here's an update of Andy's script: The way it determined the DBUS_SESSION_BUS_ADDRESS does not work on Centos 7. Also the who command did not list some sessions for some reason, so I parse the ps aux output instead. This script assumes users are logged in using X2GO (nxagent), but it should be simple to adjust for other cases.



                  #!/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 '%sn' "$processes" | grep -P "nxagent.+:d+")
                  ids=$(printf '%sn' "$processes" | grep -oP "WK:(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 '%sn' "$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





                  share|improve this answer








                  New contributor




                  jpf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.




















                    up vote
                    0
                    down vote










                    up vote
                    0
                    down vote









                    Here's an update of Andy's script: The way it determined the DBUS_SESSION_BUS_ADDRESS does not work on Centos 7. Also the who command did not list some sessions for some reason, so I parse the ps aux output instead. This script assumes users are logged in using X2GO (nxagent), but it should be simple to adjust for other cases.



                    #!/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 '%sn' "$processes" | grep -P "nxagent.+:d+")
                    ids=$(printf '%sn' "$processes" | grep -oP "WK:(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 '%sn' "$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





                    share|improve this answer








                    New contributor




                    jpf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                    Check out our Code of Conduct.









                    Here's an update of Andy's script: The way it determined the DBUS_SESSION_BUS_ADDRESS does not work on Centos 7. Also the who command did not list some sessions for some reason, so I parse the ps aux output instead. This script assumes users are logged in using X2GO (nxagent), but it should be simple to adjust for other cases.



                    #!/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 '%sn' "$processes" | grep -P "nxagent.+:d+")
                    ids=$(printf '%sn' "$processes" | grep -oP "WK:(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 '%sn' "$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






                    share|improve this answer








                    New contributor




                    jpf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                    Check out our Code of Conduct.









                    share|improve this answer



                    share|improve this answer






                    New contributor




                    jpf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                    Check out our Code of Conduct.









                    answered yesterday









                    jpf

                    101




                    101




                    New contributor




                    jpf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                    Check out our Code of Conduct.





                    New contributor





                    jpf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                    Check out our Code of Conduct.






                    jpf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                    Check out our Code of Conduct.






















                        up vote
                        -1
                        down vote













                        users=$(who | awk '{print $1}')

                        for user in $users<br>
                        do
                        DISPLAY=:0 sudo -u $user notify-send "hello!!"
                        done





                        share|improve this answer



























                          up vote
                          -1
                          down vote













                          users=$(who | awk '{print $1}')

                          for user in $users<br>
                          do
                          DISPLAY=:0 sudo -u $user notify-send "hello!!"
                          done





                          share|improve this answer

























                            up vote
                            -1
                            down vote










                            up vote
                            -1
                            down vote









                            users=$(who | awk '{print $1}')

                            for user in $users<br>
                            do
                            DISPLAY=:0 sudo -u $user notify-send "hello!!"
                            done





                            share|improve this answer














                            users=$(who | awk '{print $1}')

                            for user in $users<br>
                            do
                            DISPLAY=:0 sudo -u $user notify-send "hello!!"
                            done






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited May 17 '16 at 20:08









                            Anthon

                            60.1k17102163




                            60.1k17102163










                            answered May 17 '16 at 19:56









                            Vicent

                            1




                            1






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Unix & Linux Stack Exchange!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.





                                Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                Please pay close attention to the following guidance:


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f2881%2fshow-a-notification-across-all-running-x-displays%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                サソリ

                                広島県道265号伴広島線

                                Accessing regular linux commands in Huawei's Dopra Linux