玩转DBus命令行工具之gdbus使用

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 的优势

  1. 自动显示返回值 :不需要 --print-reply 参数
  2. 更好的类型处理:支持 variant、数组、字典等复杂类型
  3. 更清晰的输出:返回值格式更易读
  4. 内省功能 :提供 introspect 子命令
  5. 信号监听 :提供 monitor 子命令

与 dbus-send 的对比

特性 dbus-send gdbus
返回值显示 需要 --print-reply 自动显示
variant 支持 有限 完整支持
复杂类型 支持有限 完整支持
内省 需要手动调用方法 提供 introspect 子命令
信号监听 不支持 提供 monitor 子命令

注意事项

  1. 依赖:需要 GLib 库支持
  2. 参数格式 :variant 类型需要用 <> 包裹
  3. 字符串参数:字符串参数用单引号包裹
  4. 权限:系统总线操作通常需要 root 权限
  5. 标准接口支持
    • 需要服务端实现的标准接口

      • 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 连接的对象都自动支持,无需服务端显式实现。

扩展阅读

相关推荐
H_oRIZoN_11 分钟前
Linux入门DAY42【51 单片机】DS18B20 数字温度传感器完整解析(单总线原理 + 时序 + 读取流程)
linux·单片机·linux应用编程
j7~14 分钟前
【Linux网络加餐】(篇六)网络版计算器(上):模板方法模式、序列化与 JSON
linux·c++·json·序列化·反序列化·网络版计算机
weixin_3077791315 分钟前
C++代码实现MATLAB中的ode45函数功能
开发语言·c++·算法·matlab
流浪00139 分钟前
Linux系统篇34——信号(六):信号处理期间又来了怎么办?——sigaction、sa_mask、可重入函数与 volatile
linux·运维·面试·操作系统·信号处理·信号
不穿鞋的懒羊羊40 分钟前
dfs深度优先搜索
算法
学烹饪的小胡桃1 小时前
资产设备管理系统 WGFIX 怎么设置https访问
linux·运维·服务器·网络·安全
OYYHXPJR1 小时前
【算法】区间重叠模板和矩形重叠模板
算法
shehuiyuelaiyuehao1 小时前
算法46,分治快排,排序数组
java·算法·排序算法·排序
远航计算机1 小时前
GEO 选题从哪来?用一份 Query 词库把一年内容排出来
大数据·人工智能·算法·aigc
宣宣猪的小花园.1 小时前
【机器学习】神经网络与表征:为什么深度学习能自动提取特征
人工智能·嵌入式硬件·算法·机器学习