Я работал над сценарием , чтобы изменить вывод звука при подключении (отключении) экрана 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
?
У 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?
Ответ Раду, похоже, не работает для меня 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. Если вы не хотите, чтобы другие пользователи могли просматривать ваш канал, вам, вероятно, следует установить для него ограничительные разрешения.
Я искал последовательный способ уведомления всех пользователей X (как root), и мое исследование (просматривая кучу мест в сети) показало, что, хотя можно было использовать notify-send таким образом, он требовал скриптов чтобы найти информацию о сеансе DBUS и / или используемые DISPLAY и / или имена и местоположения файлов Xauthority, и даже тогда иногда люди все еще не могли заставить его работать. Таким образом, попытка отклонить уведомление-отправку на ваше желание включить вещание для пользователей X окажется ненадежной (особенно если вы обновите или измените дистрибутив в какой-то момент в будущем).
Однако ... в моей системе команда wall
работала как чудо и невероятно проста в использовании. Единственным недостатком является то, что он также транслирует сообщение на все текстовые терминалы / консоли. Если вы не против, то wall
может быть лучшим и более надежным вариантом. Примечание: пользователь, вызывающий wall
, должен иметь значение root
.
Тебе нужно позвонить с помощью sudo? Это может решить проблему.
В качестве альтернативы я обнаружил, что мне нужно установить DISPLAY=:0
и XAUTHORITY=/home/<user_name>/.Xauthority
, чтобы он работал при запуске от имени root (в данном случае из службы systemd - с помощью Environment=...
).
Вы можете использовать pynotify вместо команды оболочки. Это довольно просто и устанавливается по умолчанию в Ubuntu. Быстрый образец:
import pynotify
pynotify.init("Name")
n = pynotify.Notification("Name", "This is a notification")
n.show()