Mostra uma notificação em todos os monitores X em execução

15

Usando a linha de comando, gostaria de mostrar uma notificação em cada exibição X em execução. (e rodando console)

Algo como:

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

Existe um programa que fará isso? Se não, isso pode ser implementado com o bash?

    
por Stefan 08.10.2010 / 10:17

6 respostas

15

Você pode enviar uma mensagem para todos os consoles com a parede de comando.

Para enviar notificações sob X, há notificar-enviar que envia uma notificação para o usuário atual na exibição atual. (De sua pergunta, eu acho que você já conhece este.) Você pode construir sobre isso com alguns scripts bash. Basicamente você tem que descobrir quais usuários estão em quais X-Displays. Depois de obter essa informação, você pode usar notificar-enviar assim:

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

Onde fschmitt é o usuário na exibição 0. Você pode analisar a saída do comando "who" para localizar todos os usuários e suas exibições. A saída parece com isso

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

Veja, existem dois usuários executando sessões X, markmerk3 no display 0 e seamonkey no display 1. Eu acho que você precisa grep para tty [0-9] * e então assegure que no final da linha existe ( : [0-9.] *) Para se livrar dos logins do console e extrair o ID de exibição da string entre os parênteses.

    
por 08.10.2010 / 11:42
7

Este tópico é um pouco antigo, desculpe, mas espero que ainda possa adicionar algo útil ao tópico. (também Josef Kufner escreveu um bom script, foi um pouco longo demais para o meu gosto, e ele usa PHP)

Eu também precisava de uma ferramenta conforme descrito na pergunta original (para enviar uma mensagem para todos os usuários X ativos). E com base nas respostas aqui, eu escrevi este pequeno script somente bash, que procura por usuários X ativos (usando 'who'), e então executando o comando notify-send para cada usuário ativo.

E o melhor: você pode usar meu script exatamente como "notificar-enviar", com todos os seus parâmetros! ; -)

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

Copie o código acima em um arquivo chamado "notify-send-all", torne-o executável e copie-o para / usr / local / bin ou / usr / bin (como você gosta). Em seguida, execute-o, por exemplo como root em uma sessão de console como esta:

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

Estou usando há vários meses, em máquinas diferentes, e não tive nenhum problema até agora, e testei-o com os desktops MATE e Cinnamon. Também executando com sucesso dentro do cron e do anacron.

Eu escrevi este script para / no ArchLinux, então, por favor, me diga se você está tendo problemas em outras distribuições Linux ou desktops.

    
por 01.09.2016 / 01:36
3

Eu também precisava disso para algumas notificações em todo o sistema. Aqui está a minha solução. Ele verifica / proc para encontrar todos os busses de sessão e, em seguida, executa o comando notificar-enviar em cada um deles (uma vez por barramento). Todos os argumentos são transmitidos inalterados para notificação de envio real.

#!/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("
#!/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("%pre%", $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);
                        }
                }
        }
' -- "$@"
", $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); } } } ' -- "$@"
    
por 16.09.2015 / 16:06
1

No Ubuntu 16.04, eu queria notificações de um script em execução como root no crontab. Depois de definir as variáveis de ambiente, sudo -u $user não funcionou por algum motivo, mas sh -c "..." $user funciona.

Agora eu uso essa função:

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 
}

Como encontrar a variável DBUS_SESSION_BUS_ADDRESS provavelmente depende da sua distribuição. No Ubuntu 16.04, é em /run/user/$UID/dbus-session , que pode simplesmente ser originado. id -u é usado na função acima para obter o UID do nome de usuário retornado por who .

    
por 12.02.2017 / 11:16
0

Aqui está uma atualização do script de Andy: A maneira como determinou o DBUS_SESSION_BUS_ADDRESS não funciona no Centos 7. Além disso, o comando who não listou algumas sessões por algum motivo, então, em vez disso, analiso a saída ps aux . Este script assume que os usuários estão logados usando o X2GO ( nxagent ), mas deve ser simples de ajustar para outros casos.

#!/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
    
por 14.12.2018 / 14:45
-1
users=$(who | awk '{print $1}')

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