Проблема с `уведомить-отправить`

Я работал над сценарием , чтобы изменить вывод звука при подключении (отключении) экрана HDMI / телевизора. В основном он использует UDEV для проверки любых изменений в соединении и действует соответственно.

Все отлично работает, кроме одного: я не могу использовать notify-send, чтобы предупредить об изменениях. Я использую следующий код (output - просто оболочка для subprocess.check_output):

output("sudo -u {0} notify-send \"{1}\" \"{2}\"".format(user, title, message))

, но я вообще не получаю никаких уведомлений.

Что действительно странно, так это то, что если я запускаю hdmi_sound_toggle (как обычный пользователь или с sudo), все работает просто отлично!

Так в чем может быть проблема? Есть ли лучший способ представить уведомление, чем с помощью notify-send?

4
задан 21 September 2013 в 20:43

5 ответов

У notify-send возникают проблемы с размещением уведомлений на экране пользователя при вызове из скрипта, запускаемого пользователем root или другим пользователем.

Вы должны использовать:

output("export DISPLAY=:0; sudo -u {0} notify-send \"{1}\" \"{2}\"".format(user, title, message))

Итак, используйте:

export DISPLAY=:0

Обычно пользователь отображается на дисплее :0, но, конечно, вы можете найти, какой дисплей Пользователь использует команду who следующим образом:

who | grep -m1 ^username.*\( | awk '{print $5}' | sed 's/[(|)]//g'

Это сработало для меня в , этот скрипт .

См. Также: Можно ли запустить графическую программу на рабочем столе другого пользователя с правами root?

0
ответ дан 21 September 2013 в 20:43

Ответ Раду, похоже, не работает для меня 16.04. Вместо того, чтобы пытаться бороться с проблемой DISPLAY, которая, кажется, меняется в разных выпусках, я делаю это немного иначе. Я создаю один скрипт, который вызывается двумя способами. Правило udev вызывает скрипт, отправляя какой-то вывод в именованный канал. После входа скрипт также запускается в сервисном режиме. Здесь он слушает канал и запускает нужную команду графического интерфейса.

Например, мне нравится получать уведомления о запоминающих устройствах USB, когда они подключены, и, в частности, мне нравится знать, каков путь устройства и его серийный номер (это может показаться странным, но у меня есть веские причины ). Вот сценарий, который я использую для этого.

#!/bin/bash
# script name: usb-notify.sh
# This script needs to be called at logon with "service" parameter
# This script needs to be called by udev on USB insertion with no parameter

pipe="/tmp/usb-notifications"
if [ "$1" == "service" ]; then
    # create the named pipe that will help us trigger events from udev
    rm "$pipe"
    mkfifo "$pipe"

    # This outer while loop ensures that we can process multiple triggers
    while true
    do
        # This inner while loop reads individual trigger events
        while read info
        do
            # run some GUI command. Here, I'm running notify-send
            notify-send "USB Inserted" "$(echo -e $info)"
        done < "$pipe"
    done
else
    # Here's where udev triggers our event. If you don't need to pass any arguments
    # you  could just as easily pass an empty line as a trigger for the service.
    [ -e "$pipe" ] && echo "Device: $DEVNAME\\\nSN: $ID_SERIAL_SHORT" > "$pipe"
fi

Этот сценарий должен быть вызван двумя способами. Во-первых, необходимо создать правило udev для вызова этого скрипта. Это можно сделать с помощью следующей команды (очевидно, вы должны изменить это, чтобы посмотреть, какое устройство должно запускать ваш скрипт):

echo 'ACTION=="add",KERNEL=="sd?",RUN+="[path-to-script]/usb-notify.sh"' | sudo tee -a /etc/udev/rules.d/80-USB.rules

Во-вторых, вам нужно вызвать этот скрипт с параметром "service" при входе в систему. , Итак, откройте программу «Startup Applications» и добавьте запись, которая запускает «службу [path-to-your-script] /usb-notify.sh»

Этот сценарий можно изменить для запуска практически любого графического интерфейса пользователя приложение на события Udev. Если вы не хотите, чтобы другие пользователи могли просматривать ваш канал, вам, вероятно, следует установить для него ограничительные разрешения.

0
ответ дан 21 September 2013 в 20:43

Я искал последовательный способ уведомления всех пользователей X (как root), и мое исследование (просматривая кучу мест в сети) показало, что, хотя можно было использовать notify-send таким образом, он требовал скриптов чтобы найти информацию о сеансе DBUS и / или используемые DISPLAY и / или имена и местоположения файлов Xauthority, и даже тогда иногда люди все еще не могли заставить его работать. Таким образом, попытка отклонить уведомление-отправку на ваше желание включить вещание для пользователей X окажется ненадежной (особенно если вы обновите или измените дистрибутив в какой-то момент в будущем).

Однако ... в моей системе команда wall работала как чудо и невероятно проста в использовании. Единственным недостатком является то, что он также транслирует сообщение на все текстовые терминалы / консоли. Если вы не против, то wall может быть лучшим и более надежным вариантом. Примечание: пользователь, вызывающий wall, должен иметь значение root.

0
ответ дан 21 September 2013 в 20:43

Тебе нужно позвонить с помощью sudo? Это может решить проблему.

В качестве альтернативы я обнаружил, что мне нужно установить DISPLAY=:0 и XAUTHORITY=/home/<user_name>/.Xauthority, чтобы он работал при запуске от имени root (в данном случае из службы systemd - с помощью Environment=...).

0
ответ дан 21 September 2013 в 20:43

Вы можете использовать pynotify вместо команды оболочки. Это довольно просто и устанавливается по умолчанию в Ubuntu. Быстрый образец:

import pynotify

pynotify.init("Name")
n = pynotify.Notification("Name", "This is a notification")
n.show()
0
ответ дан 21 September 2013 в 20:43

Другие вопросы по тегам:

Похожие вопросы: