python with dasbus
With dasbus I wrote this POC:
from xml.etree import ElementTree
from dasbus.connection import SystemMessageBus
from dasbus.error import DBusError
def tree(bus, bus_name, path=None):
obj = bus.get_proxy(bus_name, path or "/")
try:
xml = obj.Introspect()
except DBusError as exc:
# implement here your exception handling
raise Exception(str(exc))
if path:
yield path
root = ElementTree.fromstring(xml)
for node in root.findall("node[@name]"):
yield from tree(bus, bus_name, (path or "") + "/" + node.attrib["name"])
if __name__ == "__main__":
bus = SystemMessageBus()
for pth in tree(bus, "org.freedesktop.login1"):
print(pth)
which outputs
/org
/org/freedesktop
/org/freedesktop/LogControl1
/org/freedesktop/login1
/org/freedesktop/login1/user
/org/freedesktop/login1/user/_1000
/org/freedesktop/login1/user/self
/org/freedesktop/login1/session
/org/freedesktop/login1/session/_326
/org/freedesktop/login1/session/_324
/org/freedesktop/login1/session/_327
/org/freedesktop/login1/session/self
/org/freedesktop/login1/session/auto
/org/freedesktop/login1/seat
/org/freedesktop/login1/seat/seat0
shell with busctl
From the shell, with systemdsystemd busctl you can use the tree command:
$ busctl tree org.freedesktop.login1
└─/org
└─/org/freedesktop
├─/org/freedesktop/LogControl1
└─/org/freedesktop/login1
├─/org/freedesktop/login1/seat
│ └─/org/freedesktop/login1/seat/seat0
├─/org/freedesktop/login1/session
│ ├─/org/freedesktop/login1/session/_324
│ ├─/org/freedesktop/login1/session/_326
│ ├─/org/freedesktop/login1/session/_327
│ ├─/org/freedesktop/login1/session/auto
│ └─/org/freedesktop/login1/session/self
└─/org/freedesktop/login1/user
├─/org/freedesktop/login1/user/_1000
└─/org/freedesktop/login1/user/self