玩转DBus命令行工具之dbus-send

dbus-send 使用指南

概述

dbus-send 是 D-Bus 最常用的命令行工具,用于发送方法调用和信号。它是 D-Bus 核心工具集的一部分,适用于快速测试和调试。

基本语法

dbus-send [--system|--session] [--print-reply] \
  --dest=服务名 对象路径 接口名.方法名 [参数]

发送方法调用

无参数方法调用

# 调用 ListNames 方法(列出所有服务名)
dbus-send --session --print-reply \
  --dest=org.freedesktop.DBus \
  /org/freedesktop/DBus \
  org.freedesktop.DBus.ListNames

带参数的方法调用

# 调用 RequestName 方法(请求服务名)
dbus-send --session --print-reply \
  --dest=org.freedesktop.DBus \
  /org/freedesktop/DBus \
  org.freedesktop.DBus.RequestName \
  string:"com.example.Service" \
  uint32:0

参数类型

  • string:"value":字符串
  • int32:123:32位整数
  • uint32:123:无符号32位整数
  • int16:123:16位整数
  • uint16:123:无符号16位整数
  • int64:123:64位整数
  • uint64:123:无符号64位整数
  • double:3.14:双精度浮点数
  • boolean:true:布尔值
  • array:string:"a","b","c":数组
  • dict:string:string:"key","value":字典

调用自定义服务方法

# 假设有一个服务 com.example.Service,对象路径 /com/example/Object
# 接口 com.example.Interface,方法 GetData,参数为字符串
dbus-send --session --print-reply \
  --dest=com.example.Service \
  /com/example/Object \
  com.example.Interface.GetData \
  string:"parameter"

访问属性

属性访问通过 org.freedesktop.DBus.Properties 接口实现。

重要说明org.freedesktop.DBus.Properties 接口需要服务端实现支持。如果服务端未实现此接口,调用会失败。

获取属性(Get)

# 获取属性值
dbus-send --session --print-reply \
  --dest=com.example.Service \
  /com/example/Object \
  org.freedesktop.DBus.Properties.Get \
  string:"com.example.Interface" \
  string:"PropertyName"

设置属性(Set)

# 设置属性值(需要将值包装在 variant 中)
# 注意:dbus-send 对 variant 支持有限,建议使用 gdbus
dbus-send --session --print-reply \
  --dest=com.example.Service \
  /com/example/Object \
  org.freedesktop.DBus.Properties.Set \
  string:"com.example.Interface" \
  string:"PropertyName" \
  variant:string:"new value"

获取所有属性(GetAll)

dbus-send --session --print-reply \
  --dest=com.example.Service \
  /com/example/Object \
  org.freedesktop.DBus.Properties.GetAll \
  string:"com.example.Interface"

内省对象

# 获取对象的 XML 描述
dbus-send --session --print-reply \
  --dest=com.example.Service \
  /com/example/Object \
  org.freedesktop.DBus.Introspectable.Introspect

重要说明org.freedesktop.DBus.Introspectable 接口需要服务端实现支持。如果服务端未实现此接口,调用会失败。此接口允许客户端动态发现对象的接口、方法、信号和属性等信息。

对象管理(ObjectManager)

org.freedesktop.DBus.ObjectManager 接口用于管理对象的生命周期,允许客户端获取服务管理的所有对象及其接口和属性。

重要说明:此接口需要服务端实现支持。通常由服务在根对象路径(如 /)上实现。

获取所有管理的对象

# 获取服务管理的所有对象及其接口和属性
dbus-send --session --print-reply \
  --dest=com.example.Service \
  / \
  org.freedesktop.DBus.ObjectManager.GetManagedObjects

返回值a{oa{sa{sv}}} 类型(嵌套字典)

  • 外层键:对象路径(object path)
  • 外层值:字典,键为接口名,值为属性字典

使用场景

  • 发现服务管理的所有对象
  • 获取对象的接口和属性信息
  • 监控对象的添加和移除(通过监听信号)

对等接口(Peer)

org.freedesktop.DBus.Peer 接口提供基本的连接检查功能。

重要说明:此接口由 D-Bus 库自动提供,不需要服务端显式实现。所有通过 D-Bus 连接的对象都自动支持此接口。

Ping - 检查连接

# 检查服务是否可用(无参数,无返回值)
dbus-send --session --print-reply \
  --dest=com.example.Service \
  /com/example/Object \
  org.freedesktop.DBus.Peer.Ping

说明:如果服务可用,方法调用会成功返回;如果服务不可用,会返回错误。

GetMachineId - 获取机器ID

# 获取连接所在机器的唯一标识符
dbus-send --session --print-reply \
  --dest=com.example.Service \
  /com/example/Object \
  org.freedesktop.DBus.Peer.GetMachineId

返回值s(string),机器的唯一标识符(UUID 格式)

使用场景

  • 检查服务是否可用(Ping)
  • 获取机器标识符(GetMachineId)
  • 测试连接状态

发送信号

# 发送信号(不需要回复)
dbus-send --session \
  --type=signal \
  /com/example/Object \
  com.example.Interface.SignalName \
  string:"signal data"

参数说明

  • --type=signal:指定消息类型为信号
  • 不需要 --dest 参数(信号是广播的)

服务管理

请求服务名

# 请求服务名(通常由服务程序自动完成)
dbus-send --session --print-reply \
  --dest=org.freedesktop.DBus \
  /org/freedesktop/DBus \
  org.freedesktop.DBus.RequestName \
  string:"com.example.Service" \
  uint32:4

标志位说明

  • 0:默认
  • 1DBUS_NAME_FLAG_ALLOW_REPLACEMENT:允许其他服务替换
  • 2DBUS_NAME_FLAG_REPLACE_EXISTING:如果已存在则替换
  • 4DBUS_NAME_FLAG_DO_NOT_QUEUE:如果已存在则不排队

释放服务名

# 释放服务名
dbus-send --session --print-reply \
  --dest=org.freedesktop.DBus \
  /org/freedesktop/DBus \
  org.freedesktop.DBus.ReleaseName \
  string:"com.example.Service"

检查服务是否存在

# 检查服务名是否有所有者
dbus-send --session --print-reply \
  --dest=org.freedesktop.DBus \
  /org/freedesktop/DBus \
  org.freedesktop.DBus.NameHasOwner \
  string:"com.example.Service"

获取服务所有者

# 获取服务名的所有者
dbus-send --session --print-reply \
  --dest=org.freedesktop.DBus \
  /org/freedesktop/DBus \
  org.freedesktop.DBus.GetNameOwner \
  string:"com.example.Service"

列出所有服务名

dbus-send --session --print-reply \
  --dest=org.freedesktop.DBus \
  /org/freedesktop/DBus \
  org.freedesktop.DBus.ListNames

列出可激活的服务

# 列出所有可激活的服务名
dbus-send --session --print-reply \
  --dest=org.freedesktop.DBus \
  /org/freedesktop/DBus \
  org.freedesktop.DBus.ListActivatableNames

实际应用示例

示例 1:查询 NetworkManager 状态

# 获取 NetworkManager 的连接状态
dbus-send --system --print-reply \
  --dest=org.freedesktop.NetworkManager \
  /org/freedesktop/NetworkManager \
  org.freedesktop.DBus.Properties.Get \
  string:"org.freedesktop.NetworkManager" \
  string:"NetworkingEnabled"

示例 2:控制媒体播放器

# 播放(假设使用 MPRIS 接口)
dbus-send --session --print-reply \
  --dest=org.mpris.MediaPlayer2.vlc \
  /org/mpris/MediaPlayer2 \
  org.mpris.MediaPlayer2.Player.Play

# 暂停
dbus-send --session --print-reply \
  --dest=org.mpris.MediaPlayer2.vlc \
  /org/mpris/MediaPlayer2 \
  org.mpris.MediaPlayer2.Player.Pause

常用选项

  • --system:使用系统总线
  • --session:使用会话总线(默认)
  • --print-reply:显示方法调用的返回值
  • --type=signal:发送信号而不是方法调用
  • --dest=服务名:指定目标服务

注意事项

  1. 返回值dbus-send 默认不显示返回值,使用 --print-reply 查看
  2. variant 类型dbus-send 对 variant 支持有限,复杂类型建议使用 gdbus
  3. 权限:系统总线操作通常需要 root 权限
  4. 服务名格式:服务名通常使用反向域名格式(如 com.example.Service
  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 连接的对象都自动支持,无需服务端显式实现。

扩展阅读

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值