Скрипт, Обрабатывающий Системные События С Помощью Dbus

Dbus — это инструмент межпроцессного взаимодействия.

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

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

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

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

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

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

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

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

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

Запускаем qdbusviewer и ищем, какой сервис может сообщить об изменении состояния сети.

На вкладке «Системная шина» мы видим сервис org.freedesktop.NetworkManager. Если в этом сервисе пройти по пути /org/freedesktop/NetworkManager, то мы найдем объект, реализующий интерфейс org.freedesktop.NetworkManager. Этот интерфейс имеет сигнал StateChanged. Проверка: щелкните сигнал правой кнопкой мыши и выберите «Подключиться».

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

Именно то, что нам нужно.

Теперь давайте добьемся того же результата в командной строке.

Мы будем использовать команду 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

То есть при каждом подключении к сети генерируется команда запуска яндекс-диска.

Наконец финальная версия:

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 отображает несколько строк для каждого полученного сигнала.

Первое содержит описание сигнала, последующие значения содержат аргументы.

Далее обрабатываем полученные сигналы по своему усмотрению.

Теги: #*nix #bash #dbus #dbus-monitor

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.