dbusサービスの下のすべてのオブジェクトパスを一覧表示する方法は?


16

これは、利用可能なDBusサービスのリストへのフォローアップの質問です。

次のPythonコードは、利用可能なすべてのDBusサービスをリストします。

import dbus
for service in dbus.SystemBus().list_names():
    print(service)

Pythonのサービスの下にオブジェクトパスをリストするにはどうすればよいですか?回答にPythonが含まれていなくてもかまいません。

Ubuntu 14.04を使用しています


回答にPythonが含まれていなくてもかまいません。
user768421

回答:


15

公式ドキュメントによると標準インターフェイスの下):

さまざまなD-Busアプリケーションに役立つ標準インターフェイスがいくつかあります。

org.freedesktop.DBus.Introspectable

このインターフェイスには1つのメソッドがあります。

org.freedesktop.DBus.Introspectable.Introspect (out STRING xml_data)

オブジェクトインスタンスは 、そのインターフェイス(信号とメソッドを含む)、オブジェクトパスツリーでその下にあるオブジェクト、およびそのプロパティを含む、オブジェクトのXML記述Introspectを返すように実装できます。

だから、ここにあなたが始めるべき非常に単純な例があります。以下を使用xml.etree.ElementTreedbusます。

#!/usr/bin/env python

import dbus
from xml.etree import ElementTree

def rec_intro(bus, service, object_path):
    print(object_path)
    obj = bus.get_object(service, object_path)
    iface = dbus.Interface(obj, 'org.freedesktop.DBus.Introspectable')
    xml_string = iface.Introspect()
    for child in ElementTree.fromstring(xml_string):
        if child.tag == 'node':
            if object_path == '/':
                object_path = ''
            new_path = '/'.join((object_path, child.attrib['name']))
            rec_intro(bus, service, new_path)

bus = dbus.SystemBus()
rec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower')

org.freedesktop.UPowerたとえば/org/freedesktop/UPower、再帰的に内省し、すべてのオブジェクトパス(ノード名)を出力します。

/org/freedesktop/UPower
/org/freedesktop/UPower/Wakeups
/org/freedesktop/UPower/devices
/org/freedesktop/UPower/devices/DisplayDevice
/org/freedesktop/UPower/devices/battery_BAT0
/org/freedesktop/UPower/devices/line_power_ADP0

これは、使用した場合に得られるものですd-feet(必要ではありません):

ここに画像の説明を入力してください


確かに、次のコマンドラインを使用して、オブジェクトパスを簡単に取得できますgdbus

gdbus introspect --system --dest org.freedesktop.UPower --object-path \
/ org / freedesktop / UPower --recurse | awk '/ ^ * node / {print $ 2}'
/ org / freedesktop / UPower
/ org / freedesktop / UPower / Wakeups
/ org / freedesktop / UPower / devices
/ org / freedesktop / UPower / devices / DisplayDevice
/ org / freedesktop / UPower / devices / battery_BAT0
/ org / freedesktop / UPower / devices / line_power_ADP0

私はqdbusインストールしていませんが、このページによると

qdbus --system org.freedesktop.UPower

同様の結果が得られます。


からオブジェクトパスのリストを作成するにはどうすればよいrec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower')ですか?
ルシッドアラム

いいえ、特定のオブジェクトパスがリストに存在するかどうかを(スクリプトで)チェックできるように、オブジェクトパスのpythonリストを作成することを意味します。それはオブジェクトパスをうまく印刷しk = rec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower')ます。関数を少し変更することで可能になると思います。
ルシッドアラム

qbusを使用したコード例:bus = dbus.SessionBus()..... obj_path = '/org/gnome/Gnote/RemoteControl'.......... cmd = 'qdbus org.gnome.Gnote'......... while obj_path not in ((subprocess.check_output(cmd, shell=True)).decode("utf-8")).split("\n"): ........pass
Khurshid Alam

@KhurshidAlam -関数などの前にリストを初期化するmylist=[]置き換え、その後printmylist.appendし、その機能ブロックの最後のコマンドとしてreturn mylistそこにあるものほとんどだ...あなたは、リストを反復処理することができますまたはスクリプトの一番下に追加何でも例えば- プレフィックスfor x in mylist: print("OBJ_PATH", x)を付けて印刷するにはOBJ_PATH
...-don_crissti

4

Pythonでこれをプログラムで実行できるかどうかはわかりません。可能性がありますが、方法を理解することは大きな頭痛の種になります。私はそれを前にやろうとしましたが、結局Dbusが嫌いになりました。とにかく物事を調査したい場合はd-feetを使用することをお勧めします。以下は私のブログから盗んだスクリーンショットです。

ここに画像の説明を入力してください

プログラム名、オブジェクトパスなどがわかったら、Pythonを使用してそれらにアクセスできます。

progname = 'org.freedesktop.NetworkManager'
objpath  = '/org/freedesktop/NetworkManager'
intfname = 'org.freedesktop.NetworkManager'
methname = 'GetDevices'

bus = dbus.SystemBus()

obj  = bus.get_object(progname, objpath)  # Here we get object
intf = dbus.Interface(obj, intfname)      # Here we get interface
meth = inf.get_dbus_method(methname)      # Here we get method

meth()                                    # And finally calling the method

お分かりのように、簡単なことを成し遂げることはお尻の痛みです。しかし、これはDbusで取得できる最も簡単なワークフローです!

そのため、GUIツールを使用してオブジェクトのパス、インターフェイスなどを見つけます。次に、上記のコードスニペットをテンプレートとして使用して、それらにアクセスします。また、IPythonのインタープリターを使用してこれを実行し、各オブジェクトが持つメソッド、プロパティなどを確認することをお勧めします(タブを押す)。



1

バス名(サービス)のオブジェクトパスを取得するために私の経験から知っていることは、オブジェクトパス '/'で内省することが可能です(上記の例を使用)

introspectfunc('org.freedesktop.UPower', '/') 

これは返されるはずです:

<node name="/"> 
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/></node>

次に、パス「/ org」でイントロスペクトします

introspectfunc('org.freedesktop.UPower', '/org')

これは返されるはずです:

<node name="/org"> 
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/></node>

等々:

introspectfunc('org.freedesktop.UPower', '/org/freedesktop')
introspectfunc('org.freedesktop.UPower', '/org/freedesktop/UPower')
etc.

これは、オブジェクトパス「/」がルートであり、すべてのノードがサブフォルダーであるハードドライブのフォルダー構造を通過するようなものです。これは、特定のバス名(サービス)のオブジェクトパスを取得し、オブジェクトパスを含むコレクションを構築する最良の方法のようです。


1

あたりとして#don_crissti答え、私が実装され、このソリューションでは、インタフェース名とメソッドと信号情報を提供します

import dbus
from xml.etree import ElementTree
bus = dbus.SystemBus()

def busNames():
    return [ name for name in  bus.list_names() if not name.startswith(":") ]


def pathNames(service,object_path="/",paths=None,serviceDict=None):
    if paths == None:
        paths = {}
    paths[object_path] = {}
    obj = bus.get_object(service, object_path)
    iface = dbus.Interface(obj, 'org.freedesktop.DBus.Introspectable')
    xml_string = iface.Introspect()
    root = ElementTree.fromstring(xml_string)
    for child in root:
        if child.tag == 'node':
            if object_path == '/':
                    object_path = ''
            new_path = '/'.join((object_path, child.attrib['name']))
            pathNames(service, new_path,paths)
        else:
            if object_path == "":
                object_path = "/"
            functiondict = {}
            paths[object_path][child.attrib["name"]] = functiondict
            for func in child.getchildren():
                if func.tag not in functiondict.keys():
                    functiondict[func.tag] =[]
                functiondict[func.tag].append(func.attrib["name"])
    if serviceDict == None:
        serviceDict = {}
    serviceDict[service] = paths
    return serviceDict



import json
import random
service=random.sample(busNames(),1).pop()
print service
print json.dumps(pathNames(service),indent=3)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.