...

пятница, 16 мая 2014 г.

Скрипт обрабатывающий события системы с помощю DBus

Dbus — средство межпроцессного взаимодействия. Другими словами, средство позволяющее одной программе «отдавать приказы» другой программе.

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



Помимо привязок к языкам программирования для Dbus существует ряд консольных программ, позволяющих использовать его из командной строки.


  • qdbus — позволяет вывести на консоль список сервисов и их интерфейсы, а также отправить команды приложениям.

  • dbus-send — позволяет отправить команды приложениям.

  • dbus-monitor — выводит на консоль информацию о полученных сигналах в момент их получения.




Также при работе с DBus представляет интерес программа qdbusviewer — графическое приложение, позволяющее изучить имеющиеся в системе программы с поддержкой DBus.

И так, обещанный пример.




Задача: написать скрипт который при установлении соединения с интернетом запустит клиент яндексдиска.

Запускаем qdbusviewer и ищем, какой сервис может сообщить об изменении состояния сети. На вкладке System bus видим сервис org.freedesktop.NetworkManager. Если в данном сервисе пройти по пути /org/freedesktop/NetworkManager, обнаружим объект реализующий интерфейс org.freedesktop.NetworkManager. В данном интерфейсе есть сигнал StateChanged. Проверяем: Жмём на сигнале правой кнопкой мыши и выбираем Connect. Отключаем, подключаем сетевой интерфейс, видим приходящие сигналы, сообщающие статус сети. То, что нам надо.

Теперь добьёмся такого же результата в командной строке. Будем использовать команду dbus-monitor. Вводим в командной строке:

dbus-monitor --system "sender=org.freedesktop.NetworkManager, path=/org/freedesktop/NetworkManager, member=StateChanged"




Здесь опция --system ­— указание слушать системную шину. В кавычках указан фильтр интересующего нас сигнала. Сервис org.freedesktop.NetworkManager, путь /org/freedesktop/NetworkManager и сигнал StateChanged.

Отключаем, подключаем сетевой интерфейс. В процессе изменения состояния сети на консоль выводятся всё новый строки:

signal sender=org.freedesktop.DBus -> dest=:1.540 serial=2 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameAcquired
string ":1.540"
signal sender=:1.2 -> dest=(null destination) serial=1870 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged
uint32 20
signal sender=:1.2 -> dest=(null destination) serial=1883 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged
uint32 40
signal sender=:1.2 -> dest=(null destination) serial=1899 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged
uint32 70




На каждый полученный сигнал выводится по 2 строки. Первая с описание сигнала, Вторая со значением аргумента. К слову, если у сигнала будет больше аргументов, то и строк будет больше.

Экспериментально определено, статусу соединённой сети соответствует значение 70.

Теперь нам надо обрабатывать получаемые сигналы и формировать команду запуска яндексдиска. Вводим в командной строке:



dbus-monitor --system "sender=org.freedesktop.NetworkManager, path=/org/freedesktop/NetworkManager, member=StateChanged" | sed -u -n 's/ uint32 70/yandex-disk start/p'




Мы дополнили предыдущую команду строкой | sed -u -n 's/ uint32 70/yandex-disk start/p'. Здесь обрабатываем каждую поступившую от dbus-monitor строку с помощью программы sed. Опция -u говорит sed-у выводить результат сразу же, не откладывая в буфер. Опция -n — не выводить ни чего, пока не будет явной команды. В одинарных кавычках указана команда программе sed: заменить в строке фразу " uint32 70" фразой «yandex-disk start» и вывести результат. Такая команда преобразует текст

signal sender=org.freedesktop.DBus -> dest=:1.540 serial=2 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameAcquired
string ":1.540"
signal sender=:1.2 -> dest=(null destination) serial=1870 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged
uint32 20
signal sender=:1.2 -> dest=(null destination) serial=1883 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged
uint32 40
signal sender=:1.2 -> dest=(null destination) serial=1899 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged
uint32 70
signal sender=:1.2 -> dest=(null destination) serial=1870 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged
uint32 20
signal sender=:1.2 -> dest=(null destination) serial=1883 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged
uint32 40
signal sender=:1.2 -> dest=(null destination) serial=1899 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=StateChanged
uint32 70




в

yandex-disk start
yandex-disk start




Т. е. при каждом соединении с сетью формируется команда yandex-disk start.

Наконец окончательный вариант:



dbus-monitor --system "sender=org.freedesktop.NetworkManager, path=/org/freedesktop/NetworkManager, member=StateChanged" | sed -u -n 's/ uint32 70/yandex-disk start/p' | sh




Отправляет сформированные команды запуска яндесдиска на исполнение.

Сохраняем в файл



#!/bin/bash
dbus-monitor --system "sender=org.freedesktop.NetworkManager, path=/org/freedesktop/NetworkManager, member=StateChanged" | sed -u -n 's/ uint32 70/yandex-disk start/p' | sh




Делаем файл исполняемым. И добавляем в автозапуск. Теперь при при соедиением с интернетом будет автоматически стартовать клиент яндексдиска.

Аналогично можно обрабатывать сигналы любых приложений поддерживающих DBus.


В статье была рассмотрена возможность автоматизировать обработку сигналов поступающих от различных приложений с помощью DBus. Для отслеживания сигналов в консоли применяется программа dbus-monitor. Данная программа позволяет отлавливать как все сигналы ото всех сервисов, так и отфильтровывать только то, что нас интересует.

Несколько примеров:



  • dbus-monitor — все согналы ото всехприложений.

  • dbus-monitor --system «sender=org.freedesktop.NetworkManager» — все сигналы от NetworkManager.

  • dbus-monitor --system «sender=org.freedesktop.NetworkManager, path=/org/freedesktop/NetworkManager» — все сигналы от объекта /org/freedesktop/NetworkManager в сервисе NetworkManager.

  • dbus-monitor --system «sender=org.freedesktop.NetworkManager, path=/org/freedesktop/NetworkManager, member=StateChanged» — только сигнал StateChanged от объекта /org/freedesktop/NetworkManager в сервисе NetworkManager




dbus-monitor на каждый полученный сигнал выводит несколько строк. В первой описание сигнала, в последующих значения аргументов.

Далее обрабатываем получаемые сигналы, как нам заблагорассудится.

This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий