gdbus 使用指南
概述
gdbus 是 GLib 提供的 D-Bus 工具集,功能比 dbus-send 更强大,支持复杂类型(variant、数组等),自动显示返回值,提供更好的类型处理。
基本语法
调用方法
bash
gdbus call [--system|--session] \
--dest=服务名 \
--object-path=对象路径 \
--method=接口名.方法名 [参数...]
内省对象
bash
gdbus introspect [--system|--session] \
--dest=服务名 \
--object-path=对象路径
监听信号
bash
gdbus monitor [--system|--session] \
--dest=服务名 \
--object-path=对象路径
方法调用
无参数方法调用
bash
gdbus call --session \
--dest=org.freedesktop.DBus \
--object-path=/org/freedesktop/DBus \
--method=org.freedesktop.DBus.ListNames
带参数的方法调用
bash
gdbus call --session \
--dest=com.example.Service \
--object-path=/com/example/Object \
--method=com.example.Interface.GetData "parameter"
多个参数
bash
gdbus call --session \
--dest=com.example.Service \
--object-path=/com/example/Object \
--method=com.example.Interface.SetData "param1" "param2" 123
访问属性
属性访问通过 org.freedesktop.DBus.Properties 接口实现。
重要说明 :org.freedesktop.DBus.Properties 接口需要服务端实现支持。如果服务端未实现此接口,调用会失败。
获取属性
bash
gdbus call --session \
--dest=com.example.Service \
--object-path=/com/example/Object \
--method=org.freedesktop.DBus.Properties.Get \
"com.example.Interface" "PropertyName"
设置属性
bash
gdbus call --session \
--dest=com.example.Service \
--object-path=/com/example/Object \
--method=org.freedesktop.DBus.Properties.Set \
"com.example.Interface" "PropertyName" "<'new value'>"
注意 :设置属性时,值需要用 <> 包裹,字符串用单引号。
获取所有属性
bash
gdbus call --session \
--dest=com.example.Service \
--object-path=/com/example/Object \
--method=org.freedesktop.DBus.Properties.GetAll \
"com.example.Interface"
内省对象
bash
# 内省对象
gdbus introspect --session \
--dest=com.example.Service \
--object-path=/com/example/Object
重要说明 :org.freedesktop.DBus.Introspectable 接口需要服务端实现支持。如果服务端未实现此接口,调用会失败。此接口允许客户端动态发现对象的接口、方法、信号和属性等信息。
输出示例:
node /com/example/Object {
interface com.example.Interface {
methods:
GetData(out s result);
Echo(in s input,
out s output);
signals:
DataChanged(s data);
properties:
@org.freedesktop.DBus.Property.EmitsChangedSignal = 'false'
readwrite s Data = 'default value';
};
interface org.freedesktop.DBus.Properties {
methods:
Get(in s interface_name,
in s property_name,
out v value);
Set(in s interface_name,
in s property_name,
in v value);
GetAll(in s interface_name,
out a{sv} properties);
signals:
PropertiesChanged(s interface_name,
a{sv} changed_properties,
as invalidated_properties);
};
interface org.freedesktop.DBus.Introspectable {
methods:
Introspect(out s xml_data);
};
};
注意 :gdbus introspect 的输出格式是易读的文本格式,而不是 XML。如果需要 XML 格式,可以使用 dbus-send 调用 Introspect 方法。
监听信号
bash
# 监听信号
gdbus monitor --session \
--dest=com.example.Service \
--object-path=/com/example/Object
类型处理
variant 类型
gdbus 对 variant 类型有更好的支持:
bash
# 设置 variant 类型的属性
gdbus call --session \
--dest=com.example.Service \
--object-path=/com/example/Object \
--method=org.freedesktop.DBus.Properties.Set \
"com.example.Interface" "VariantProperty" "<123>"
数组类型
bash
# 传递数组参数
gdbus call --session \
--dest=com.example.Service \
--object-path=/com/example/Object \
--method=com.example.Interface.ProcessArray \
"['item1', 'item2', 'item3']"
字典类型
bash
# 传递字典参数
gdbus call --session \
--dest=com.example.Service \
--object-path=/com/example/Object \
--method=com.example.Interface.ProcessDict \
"{'key1': 'value1', 'key2': 'value2'}"
实际应用示例
示例 1:获取服务属性
bash
# 获取 D-Bus 服务的特性列表(示例:使用 org.freedesktop.DBus 服务)
gdbus call --session \
--dest=org.freedesktop.DBus \
--object-path=/org/freedesktop/DBus \
--method=org.freedesktop.DBus.Properties.Get \
"org.freedesktop.DBus" "Features"
# 注意:如果系统中有 MPRIS 媒体播放器运行,可以使用以下命令获取播放状态:
# gdbus call --session \
# --dest=org.mpris.MediaPlayer2.vlc \
# --object-path=/org/mpris/MediaPlayer2 \
# --method=org.freedesktop.DBus.Properties.Get \
# "org.mpris.MediaPlayer2.Player" "PlaybackStatus"
示例 2:查询系统服务信息
bash
# 获取 D-Bus 服务的接口列表
gdbus call --session \
--dest=org.freedesktop.DBus \
--object-path=/org/freedesktop/DBus \
--method=org.freedesktop.DBus.Properties.Get \
"org.freedesktop.DBus" "Interfaces"
# 注意:如果系统中有 UPower 服务运行,可以使用以下命令获取电池信息:
# gdbus call --system \
# --dest=org.freedesktop.UPower \
# --object-path=/org/freedesktop/UPower/devices/battery_BAT0 \
# --method=org.freedesktop.DBus.Properties.Get \
# "org.freedesktop.UPower.Device" "Percentage"
示例 3:查看对象树
bash
# 使用 ObjectManager 查看所有对象
gdbus call --session \
--dest=com.example.Service \
--object-path=/ \
--method=org.freedesktop.DBus.ObjectManager.GetManagedObjects
重要说明 :org.freedesktop.DBus.ObjectManager 接口需要服务端实现支持。通常由服务在根对象路径(如 /)上实现。
示例 4:检查服务连接
bash
# 使用 Peer.Ping 测试服务是否可用
gdbus call --session \
--dest=com.example.Service \
--object-path=/com/example/Object \
--method=org.freedesktop.DBus.Peer.Ping
返回值说明:
- 如果服务可用,返回
()(空括号),表示方法调用成功,但Ping方法没有返回值 - 如果服务不可用,返回错误:
Error: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown
判断连接成功 :返回 () 表示连接成功;返回错误信息表示服务不存在或不可用。
bash
# 获取机器ID
gdbus call --session \
--dest=com.example.Service \
--object-path=/com/example/Object \
--method=org.freedesktop.DBus.Peer.GetMachineId
返回值说明 :返回机器的唯一标识符(UUID 格式),例如:('550e8400-e29b-41d4-a716-446655440000',)
重要说明 :org.freedesktop.DBus.Peer 接口由 D-Bus 库自动提供,不需要服务端显式实现。所有通过 D-Bus 连接的对象都自动支持此接口。
常用选项
--system:使用系统总线--session:使用会话总线(默认)--dest=服务名:指定目标服务--object-path=路径:指定对象路径--method=接口.方法:指定方法名
gdbus 的优势
- 自动显示返回值 :不需要
--print-reply参数 - 更好的类型处理:支持 variant、数组、字典等复杂类型
- 更清晰的输出:返回值格式更易读
- 内省功能 :提供
introspect子命令 - 信号监听 :提供
monitor子命令
与 dbus-send 的对比
| 特性 | dbus-send |
gdbus |
|---|---|---|
| 返回值显示 | 需要 --print-reply |
自动显示 |
| variant 支持 | 有限 | 完整支持 |
| 复杂类型 | 支持有限 | 完整支持 |
| 内省 | 需要手动调用方法 | 提供 introspect 子命令 |
| 信号监听 | 不支持 | 提供 monitor 子命令 |
注意事项
- 依赖:需要 GLib 库支持
- 参数格式 :variant 类型需要用
<>包裹 - 字符串参数:字符串参数用单引号包裹
- 权限:系统总线操作通常需要 root 权限
- 标准接口支持 :
-
需要服务端实现的标准接口:
org.freedesktop.DBus.Properties:属性访问接口(Get、Set、GetAll)org.freedesktop.DBus.Introspectable:内省接口(Introspect)org.freedesktop.DBus.ObjectManager:对象管理接口(GetManagedObjects)
如果服务端未实现这些接口,相应的调用会失败并返回错误。客户端在调用前应检查服务是否支持所需接口。
-
自动提供的标准接口:
org.freedesktop.DBus.Peer:对等接口(Ping、GetMachineId)
此接口由 D-Bus 库自动提供,所有通过 D-Bus 连接的对象都自动支持,无需服务端显式实现。
-
扩展阅读
man gdbus- GLib D-Bus 文档