Dbus — это инструмент межпроцессного взаимодействия.
Другими словами, средство, позволяющее одной программе «отдавать приказы» другой программе.
В Интернете легко найти примеры того, как управлять различными программами из командной строки с помощью DBus. А вот тема, как отслеживать сигналы, исходящие от других программ, освещена слабо.
В этой статье я хочу исправить эту несправедливость и разобрать пример обработки событий, полученных от системы по Dbus. Помимо привязок языка программирования для Dbus, существует ряд консольных программ, позволяющих использовать его из командной строки.
- qdbus — позволяет отображать на консоли список сервисов и их интерфейсов, а также отправлять команды приложениям.
- dbus-send — позволяет отправлять команды приложениям.
- dbus-monitor — выводит на консоль информацию о полученных сигналах в момент их поступления.
И так, обещанный пример.
Задача: написать скрипт, который при установлении соединения с интернетом будет запускать клиент Яндексдиска.
Запускаем qdbusviewer и ищем, какой сервис может сообщить об изменении состояния сети.
На вкладке «Системная шина» мы видим сервис org.freedesktop.NetworkManager. Если в этом сервисе пройти по пути /org/freedesktop/NetworkManager, то мы найдем объект, реализующий интерфейс org.freedesktop.NetworkManager. Этот интерфейс имеет сигнал StateChanged. Проверка: щелкните сигнал правой кнопкой мыши и выберите «Подключиться».
Отключаем и подключаем сетевой интерфейс, видим входящие сигналы, указывающие состояние сети.
Именно то, что нам нужно.
Теперь давайте добьемся того же результата в командной строке.
Мы будем использовать команду dbus-monitor. Введите в командной строке:
Здесь --system ? опция — это инструкция для прослушивания системной шины.dbus-monitor --system "sender=org.freedesktop.NetworkManager, path=/org/freedesktop/NetworkManager, member=StateChanged"
В кавычках указан фильтр интересующего нас сигнала.
Служба 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
Первое содержит описание сигнала, последующие значения содержат аргументы.
Далее обрабатываем полученные сигналы по своему усмотрению.
Теги: #*nix #bash #dbus #dbus-monitor
-
Whatsapp Запустит Веб-Версию Мессенджера
19 Oct, 24 -
Не Заменяйте Цели Средствами – 2
19 Oct, 24 -
Прощай, Табло! Привет, Файн Би
19 Oct, 24 -
Рамблер Берет За Качество?
19 Oct, 24 -
Хайку. Начало
19 Oct, 24 -
Что Такое Фотоблог?
19 Oct, 24