Как перечислить все пути объектов под dbus-службой, используя только командную строку dbus?

Вопрос или проблема

Как я могу перечислить пути объектов в службах dbus, используя ТОЛЬКО утилиту командной строки dbus-send?

На данный момент я могу только перечислить службы:

dbus-send --system --dest=org.freedesktop.DBus --type=method_call --print-reply  /org/freedesktop/DBus org.freedesktop.DBus.ListNames

или интерфейсы:

dbus-send --system --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.Introspectable.Introspect

Этот вопрос очень похож на:

Как перечислить все пути объектов в службе dbus?

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

Я использую закрытую встроенную систему и не могу ничего установить, поэтому не могу использовать никакие из следующих утилит:

  • qdbusviewer
  • qdbus
  • d-feet
  • python

Вы можете использовать метод GetManagedObjects в интерфейсе org.freedesktop.DBus.ObjectManager. Но он не просто выведет список путей, а предоставит всю информацию об объекте, поэтому вам нужно будет извлечь пути из выводимого словаря.

Если busctl (из systemd) доступен для вас, я бы порекомендовал его использовать, так как он имеет JSON-вывод, который можно обработать с помощью jq. Пример для JSON-дампа UDisks2:

# busctl call org.freedesktop.UDisks2 /org/freedesktop/UDisks2 org.freedesktop.DBus.ObjectManager GetManagedObjects --json=short | jq ".data[0] | keys[]"
"/org/freedesktop/UDisks2/Manager"
"/org/freedesktop/UDisks2/block_devices/sda"
"/org/freedesktop/UDisks2/block_devices/sda1"
...

В случае с dbus-send вызов будет выглядеть так

# dbus-send --system --dest=org.freedesktop.UDisks2 --type=method_call --print-reply  /org/freedesktop/UDisks2 org.freedesktop.DBus.ObjectManager.GetManagedObjects

но вам нужно будет вручную обработать вывод.

Редактировать: Для org.bluez команды будут:

# busctl call org.bluez / org.freedesktop.DBus.ObjectManager GetManagedObjects --json pretty | jq ".data[0] | keys[]"
"/org/bluez"
"/org/bluez/hci0"
"/org/bluez/hci0/dev_00_1B_66_C1_56_01"

и

# dbus-send --system --dest=org.bluez --type=method_call --print-reply  / org.freedesktop.DBus.ObjectManager.GetManagedObject

и вы можете попробовать что-то вроде

# dbus-send --system --dest=org.bluez --type=method_call --print-reply  / org.freedesktop.DBus.ObjectManager.GetManagedObjects | grep -A 1 "dict entry" | grep "object path" | cut -d"\"" -f2
/org/bluez
/org/bluez/hci0
/org/bluez/hci0/dev_00_1B_66_C1_56_01

чтобы обработать вывод и получить только пути объектов.

Ответ или решение

Для работы с D-Bus в условиях ограниченных возможностей, например, на закрытой встроенной системе, где нельзя установить дополнительные утилиты, такие как qdbus, d-feet или python, приходится использовать доступные инструменты. dbus-send — одна из таких утилит, которая доступна во многих системах и может быть использована для взаимодействия с D-Bus. Однако, она имеет некоторые ограничения в плане удобства и формата представления данных.

Теория

D-Bus (Desktop Bus) — это система межпроцессного взаимодействия, разработанная для Linux. Она обеспечивает взаимодействие между различными приложениями и компонентами системы, предоставляя стандартный способ для передачи сообщений между процессами. Каждое приложение или служба имеет свой набор объектов и интерфейсов, через которые предоставляются те или иные функции.

Каждый объект в D-Bus представляется уникальным путем (object path), через который можно обращаться к его методам, и может реализовывать один или несколько интерфейсов. Чтобы получить список всех доступных объектов, необходимо обратиться к методу GetManagedObjects интерфейса org.freedesktop.DBus.ObjectManager.

Пример

Если вам необходимо получить список всех объектов для определенного D-Bus сервиса, например, для org.bluez, можно использовать следующую команду:

dbus-send --system --dest=org.bluez --type=method_call --print-reply / org.freedesktop.DBus.ObjectManager.GetManagedObjects

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

Применение

Чтобы извлечь только пути объектов из ответа, потребуется применить фильтрацию текста. В Unix-подобных системах для этого можно использовать некоторые команды для обработки текста, даже при отсутствии специализированных инструментов типа jq для обработки JSON.

Вот пример команды, которая извлекает только пути объектов:

dbus-send --system --dest=org.bluez --type=method_call --print-reply / org.freedesktop.DBus.ObjectManager.GetManagedObjects | grep -A 1 "dict entry" | grep "object path" | cut -d"\"" -f2

Эта команда работает следующим образом:

  1. grep -A 1 "dict entry" отбирает строки с "dict entry" и следующую за ними строку, так как пути объектов могут идти следом.
  2. grep "object path" фильтрует строки, содержащие "object path".
  3. cut -d"\"" -f2 извлекает часть строки, заключенную в двойные кавычки, в которой содержится сам путь объекта.

Эти команды вместе позволяют получить список всех путей объектов сервиса org.bluez в более читаемой форме.

Заключение

Таким образом, используя команду dbus-send и инструменты для фильтрации и обработки текстов, можно обойти ограничения, связанные с отсутствием более мощных утилит для работы с D-Bus на встраиваемых системах. Хотя процесс может показаться менее интуитивным по сравнению с использованием специальных утилит, он предоставляет необходимую гибкость для решения поставленной задачи. Важно помнить, что такие подходы требуют хорошего понимания структуры ответов D-Bus и навыков работы с командной строкой Linux для эффективного извлечения и обработки информации.

Оцените материал
Добавить комментарий

Капча загружается...