D-Bus 有什么实际用途?

400*_*Cat 51 openbox gui desktop-environment d-bus

dbus 应该提供“一种应用程序相互通信的简单方法”。

但我仍然不确定它实际上有什么用处。我从未见过dbus有用的情况,我只看到某些dbus组件遇到错误的警告,例如当我从命令行启动终止符时(以便我可以看到错误):

Error retrieving accessibility bus address: org.freedesktop.DBus.Error.ServiceUnknown: The name org.a11y.Bus was not provided by any .service files
Run Code Online (Sandbox Code Playgroud)

我通过添加NO_AT_BRIDGE=1/etc/environment. 我不知道那有什么作用。

几乎所有 gui 应用程序似乎都与dbus. 有些允许在没有 的情况下启动dbus,即:

terminator --no-dbus
Run Code Online (Sandbox Code Playgroud)

我看不出行为有什么不同。什么应该停止工作,什么时候terminator开始没有dbus

另外,我尝试禁用各种 dbus 组件以查看停止工作的内容:

我删除了/etc/X11/Xsession.d/95dbus_update-activation-env只是为了看看会发生什么。它包含以下代码:

if [ -n "$DBUS_SESSION_BUS_ADDRESS" ] && [ -x "/usr/bin/dbus-update-activation-environment" ]; then
  # subshell so we can unset environment variables
  (
    # unset login-session-specifics
    unset XDG_SEAT
    unset XDG_SESSION_ID
    unset XDG_VTNR

    # tell dbus-daemon --session to put the Xsession's environment in activated services' environments
    dbus-update-activation-environment --verbose --all
  )
fi
Run Code Online (Sandbox Code Playgroud)

据我所知,一切都一样。上述脚本的目的是什么?

在什么情况下,我的应用程序通过 相互交谈会很有用dbus

是否有没有 就不能工作的应用程序dbus

我的系统是 Debian Buster,我使用的是普通的 openbox 环境(没有任何桌面环境,如 Gnome 或 KDE)

Ste*_*art 46

dbus 完全按照您说的做:它允许应用程序之间进行双向通信。


对于您提到的具体示例terminator。从终结者的手册页,我们看到:

--new-tab
    If this is specified and Terminator is already running, DBus 
    will be used to spawn a new tab in the first Terminator window.
Run Code Online (Sandbox Code Playgroud)

因此,如果您从另一个终端(konsole、xterm、gnome-terminal)执行此操作:

$ terminator &
$ terminator --new-tab &
Run Code Online (Sandbox Code Playgroud)

您将看到第一个命令打开一个新窗口。第二个命令在第一个窗口中打开一个新选项卡。这是由第二个进程使用 dbus 找到第一个进程完成的,要求它打开一个新选项卡,然后退出。

如果您从另一个终端执行此操作:

$ terminator --no-dbus &
$ terminator --new-tab &
Run Code Online (Sandbox Code Playgroud)

您将看到第一个命令打开一个新窗口。第二个命令无法找到第一个窗口的 dbus,因此它启动一个新窗口。我安装了终结者来测试这个,这是真的。

另外,我怀疑 polkit 会受到影响。Polkit 使用 dbus 来提升 GUI 应用程序的权限。这就像sudoGUI 世界的 。如果您在 gnome 中,并且在要求您输入管理员密码时看到整个屏幕都被覆盖了,那么这就是 polkit 的作用。我怀疑terminator如果你有--no-dbus. 它要么无法通过身份验证,要么回退到某些终端身份验证。从terminator尝试pkexec ls。这将以ls提升的权限运行。看看有和没有--no-dbus选项是否不同。我的窗口管理器 (i3) 中没有 polkit 代理,因此我无法对此进行测试。


我主要了解 systemd 方面的 dbus,所以这就是我其余答案的来源。

是否有没有 就不能工作的应用程序dbus

是的。拿systemctlsystemctl status将向 发出查询"org.freedesktop.systemd1",并将其呈现给您。 systemctl start将调用 dbus 方法并将单元作为参数传递给该方法。 systemd接收呼叫并执行操作。

如果您想对 systemd 单元(即 foo.service)更改状态采取行动,您可以获取org.freedesktop.DBus.Properties带有 path/org/freedesktop/systemd1/unit/foo_2eservice和 member接口的文件描述符PropertiesChangedinotify在那个 FD 上设置一个,你突然有办法对服务的启动、停止、失败等做出反应。

如果您想查看 systemd dbus 上特定单元的可用内容(即ssh.service),请尝试以下命令:

busctl introspect \
    org.freedesktop.systemd1 \
    /org/freedesktop/systemd1/unit/ssh_2eservice
NAME                                TYPE      SIGNATURE       RESULT/VALUE                             FLAGS
org.freedesktop.DBus.Introspectable interface -               -                                        -
.Introspect                         method    -               s                                        -
org.freedesktop.DBus.Peer           interface -               -                                        -
.GetMachineId                       method    -               s                                        -
.Ping                               method    -               -                                        -
org.freedesktop.DBus.Properties     interface -               -                                        -
.Get                                method    ss              v                                        -
.GetAll                             method    s               a{sv}                                    -
.Set                                method    ssv             -                                        -
.PropertiesChanged                  signal    sa{sv}as        -                                        -
org.freedesktop.systemd1.Service    interface -               -                                        -
.AttachProcesses                    method    sau             -                                        -
.GetProcesses                       method    -               a(sus)                                   -
.AllowedCPUs                        property  ay              0                                        -
.AllowedMemoryNodes                 property  ay              0                                        -
.AmbientCapabilities                property  t               0                                        const
.AppArmorProfile                    property  (bs)            false ""                                 const
.BindPaths                          property  a(ssbt)         0                                        const
.BindReadOnlyPaths                  property  a(ssbt)         0                                        const
.BlockIOAccounting                  property  b               false                                    -
.BlockIODeviceWeight                property  a(st)           0                                        -
.BlockIOReadBandwidth               property  a(st)           0                                        -
.BlockIOWeight                      property  t               18446744073709551615                     -
.BlockIOWriteBandwidth              property  a(st)           0                                        -
.BusName                            property  s               ""                                       const
.CPUAccounting                      property  b               false                                    -
.CPUAffinity                        property  ay              0                                        const
.CPUAffinityFromNUMA                property  b               false                                    const
.CPUQuotaPerSecUSec                 property  t               18446744073709551615                     -
.CPUQuotaPeriodUSec                 property  t               18446744073709551615                     -
.CPUSchedulingPolicy                property  i               0                                        const
.CPUSchedulingPriority              property  i               0                                        const
.CPUSchedulingResetOnFork           property  b               false                                    const
.CPUShares                          property  t               18446744073709551615                     -
.CPUUsageNSec                       property  t               18446744073709551615                     -
.CPUWeight                          property  t               18446744073709551615                     -
.CacheDirectory                     property  as              0                                        const
.CacheDirectoryMode                 property  u               493                                      const
.CapabilityBoundingSet              property  t               18446744073709551615                     const
.CleanResult                        property  s               "success"                                emits-change
.ConfigurationDirectory             property  as              0                                        const
.ConfigurationDirectoryMode         property  u               493                                      const
.ControlGroup                       property  s               "/system.slice/ssh.service"              -
.ControlPID                         property  u               0                                        emits-change
.CoredumpFilter                     property  t               51                                       const
.DefaultMemoryLow                   property  t               0                                        -
.DefaultMemoryMin                   property  t               0                                        -
.Delegate                           property  b               false                                    -
.DelegateControllers                property  as              0                                        -
.DeviceAllow                        property  a(ss)           0                                        -
.DevicePolicy                       property  s               "auto"                                   -
.DisableControllers                 property  as              0                                        -
.DynamicUser                        property  b               false                                    const
.EffectiveCPUs                      property  ay              0                                        -
.EffectiveMemoryNodes               property  ay              0                                        -
.Environment                        property  as              0                                        const
.EnvironmentFiles                   property  a(sb)           1 "/etc/default/ssh" true                const
.ExecCondition                      property  a(sasbttttuii)  0                                        emits-invalidation
.ExecConditionEx                    property  a(sasasttttuii) 0                                        emits-invalidation
.ExecMainCode                       property  i               0                                        emits-change
.ExecMainExitTimestamp              property  t               0                                        emits-change
.ExecMainExitTimestampMonotonic     property  t               0                                        emits-change
.ExecMainPID                        property  u               835                                      emits-change
.ExecMainStartTimestamp             property  t               1597235861087584                         emits-change
.ExecMainStartTimestampMonotonic    property  t               5386565                                  emits-change
.ExecMainStatus                     property  i               0                                        emits-change
.ExecReload                         property  a(sasbttttuii)  2 "/usr/sbin/sshd" 2 "/usr/sbin/sshd" "… emits-invalidation
.ExecReloadEx                       property  a(sasasttttuii) 2 "/usr/sbin/sshd" 2 "/usr/sbin/sshd" "… emits-invalidation
.ExecStart                          property  a(sasbttttuii)  1 "/usr/sbin/sshd" 3 "/usr/sbin/sshd" "… emits-invalidation
.ExecStartEx                        property  a(sasasttttuii) 1 "/usr/sbin/sshd" 3 "/usr/sbin/sshd" "… emits-invalidation
.ExecStartPost                      property  a(sasbttttuii)  0                                        emits-invalidation
.ExecStartPostEx                    property  a(sasasttttuii) 0                                        emits-invalidation
.ExecStartPre                       property  a(sasbttttuii)  1 "/usr/sbin/sshd" 2 "/usr/sbin/sshd" "… emits-invalidation
.ExecStartPreEx                     property  a(sasasttttuii) 1 "/usr/sbin/sshd" 2 "/usr/sbin/sshd" "… emits-invalidation
.ExecStop                           property  a(sasbttttuii)  0                                        emits-invalidation
.ExecStopEx                         property  a(sasasttttuii) 0                                        emits-invalidation
.ExecStopPost                       property  a(sasbttttuii)  0                                        emits-invalidation
.ExecStopPostEx                     property  a(sasasttttuii) 0                                        emits-invalidation
.FileDescriptorStoreMax             property  u               0                                        const
.FinalKillSignal                    property  i               9                                        const
.GID                                property  u               4294967295                               emits-change
.Group                              property  s               ""                                       const
.GuessMainPID                       property  b               true                                     const
.IOAccounting                       property  b               false                                    -
.IODeviceLatencyTargetUSec          property  a(st)           0                                        -
.IODeviceWeight                     property  a(st)           0                                        -
.IOReadBandwidthMax                 property  a(st)           0                                        -
.IOReadBytes                        property  t               18446744073709551615                     -
.IOReadIOPSMax                      property  a(st)           0                                        -
.IOReadOperations                   property  t               18446744073709551615                     -
.IOSchedulingClass                  property  i               0                                        const
.IOSchedulingPriority               property  i               0                                        const
.IOWeight                           property  t               18446744073709551615                     -
.IOWriteBandwidthMax                property  a(st)           0                                        -
.IOWriteBytes                       property  t               18446744073709551615                     -
.IOWriteIOPSMax                     property  a(st)           0                                        -
.IOWriteOperations                  property  t               18446744073709551615                     -
.IPAccounting                       property  b               false                                    -
.IPAddressAllow                     property  a(iayu)         0                                        -
.IPAddressDeny                      property  a(iayu)         0                                        -
.IPEgressBytes                      property  t               18446744073709551615                     -
.IPEgressFilterPath                 property  as              0                                        -
.IPEgressPackets                    property  t               18446744073709551615                     -
.IPIngressBytes                     property  t               18446744073709551615                     -
.IPIngressFilterPath                property  as              0                                        -
.IPIngressPackets                   property  t               18446744073709551615                     -
.IgnoreSIGPIPE                      property  b               true                                     const
.InaccessiblePaths                  property  as              0                                        const
...skipping...
.CollectMode                        property  s               "inactive"                               const
.ConditionResult                    property  b               true                                     emits-change
.ConditionTimestamp                 property  t               1597235861034899                         emits-change
.ConditionTimestampMonotonic        property  t               5333881                                  emits-change
.Conditions                         property  a(sbbsi)        1 "ConditionPathExists" false true "/et… emits-invalidation
.ConflictedBy                       property  as              0                                        const
.Conflicts                          property  as              1 "shutdown.target"                      const
.ConsistsOf                         property  as              0                                        const
.DefaultDependencies                property  b               true                                     const
.Description                        property  s               "OpenBSD Secure Shell server"            const
.Documentation                      property  as              2 "man:sshd(8)" "man:sshd_config(5)"     const
.DropInPaths                        property  as              0                                        const
.FailureAction                      property  s               "none"                                   const
.FailureActionExitStatus            property  i               -1                                       const
.Following                          property  s               ""                                       -
.FragmentPath                       property  s               "/lib/systemd/system/ssh.service"        const
.FreezerState                       property  s               "running"                                emits-change
.Id                                 property  s               "ssh.service"                            const
.IgnoreOnIsolate                    property  b               false                                    const
.InactiveEnterTimestamp             property  t               0                                        emits-change
.InactiveEnterTimestampMonotonic    property  t               0                                        emits-change
.InactiveExitTimestamp              property  t               1597235861039525                         emits-change
.InactiveExitTimestampMonotonic     property  t               5338505                                  emits-change
.InvocationID                       property  ay              16 90 215 118 165 228 162 72 57 179 144… emits-change
.Job                                property  (uo)            0 "/"                                    emits-change
.JobRunningTimeoutUSec              property  t               18446744073709551615                     const
.JobTimeoutAction                   property  s               "none"                                   const
.JobTimeoutRebootArgument           property  s               ""                                       const
.JobTimeoutUSec                     property  t               18446744073709551615                     const
.JoinsNamespaceOf                   property  as              0                                        const
.LoadError                          property  (ss)            "" ""                                    const
.LoadState                          property  s               "loaded"                                 const
.Names                              property  as              2 "ssh.service" "sshd.service"           const
.NeedDaemonReload                   property  b               false                                    const
.OnFailure                          property  as              0                                        const
.OnFailureJobMode                   property  s               "replace"                                const
.PartOf                             property  as              0                                        const
.Perpetual                          property  b               false                                    const
.PropagatesReloadTo                 property  as              0                                        const
.RebootArgument                     property  s               ""                                       const
.Refs                               property  as              0                                        -
.RefuseManualStart                  property  b               false                                    const
.RefuseManualStop                   property  b               false                                    const
.ReloadPropagatedFrom               property  as              0                                        const
.RequiredBy                         property  as              0                                        const
.Requires                           property  as              3 "system.slice" "-.mount" "sysinit.tar… const
.RequiresMountsFor                  property  as              1 "/run/sshd"                            const
.Requisite                          property  as              0                                        const
.RequisiteOf                        property  as              0                                        const
.SourcePath                         property  s               ""                                       const
.StartLimitAction                   property  s               "none"                                   const
.StartLimitBurst                    property  u               5                                        const
.StartLimitIntervalUSec             property  t               10000000                                 const
.StateChangeTimestamp               property  t               1597235861208937                         emits-change
.StateChangeTimestampMonotonic      property  t               5507917                                  emits-change
.StopWhenUnneeded                   property  b               fal

  • **DO** 程序“只是通过套接字进行通信”,因为 DBus 是在它们之上实现的。但是当你“只是通过套接字通信”时,你必须说哪些套接字和什么协议。DBus 可以回答这些问题——让您找到实现您想要做的事情的对等点并指定一般格式。 (14认同)
  • @BenPen 本地进程的服务发现主要由桌面/GUI 使用驱动。虽然 Linux 确实有一些公司在朝这个方向推动它,但我不知道桌面 UNIX 公司。你可以在 BSD 上使用 D-Bus,但大多数设置只使用一个简单的 D-Bus 来让 GNOME/KDE 像 Jörg 所说的那样运行。关于 D-Bus 和 logind/systemd/... 的更大图景存在相当多的怀疑,因为它将系统从主要以 shell 驱动的以高级用户为中心的系统转变为“现代”桌面。因此,这些功能通常被认为是臃肿的。 (4认同)
  • 我不确定你的解释是否有道理。TCP 套接字确实占用端口,但对于本地 IPC,大多数软件无论如何都不会使用它们——它会使用只占用路径名的本地“Unix”套接字。(您会发现许多守护进程在 /run 下具有本地套接字,甚至您的 systemctl 示例实际上也会使用专用套接字与 systemd 通信,以防系统 D-Bus 总线不可用。) (3认同)
  • @SimonRichter 我的措辞很有趣,因为它是一个与 Windows 的 COM 目的相似的系统,但更轻巧,攻击面也更小。- 它肯定没有那么多,但这就是重点。 (3认同)
  • @SimonRichter 这不是我对轻量级的意思。整个 COM 模型要重得多。哪个*确实*使它更快,因为它可以做一些事情,比如在调用者的进程中加载​​服务,完全绕过IPC。使这成为可能的机制比 dbus 更重、更复杂,dbus 最终只是在套接字顶部非常薄的一层。 (2认同)

ljr*_*jrk 25

@Stewart 已经对 D-Bus 进行了深入深入的回答,但我想用一个关于 D-Bus 设计的高层次想法来修改它。

UNIX 和 Linux 系统上进程间通信 (IPC) 的“传统”方式直接使用套接字,例如进程 A 打开/var/run/a.socket并且进程 B 对其进行读/写。这对于旨在共同通信的紧密结合的程序来说非常有效。

但是,您可能希望在编写程序 A 时程序 B 甚至不存在的两个程序的进程之间进行通信。D-Bus 试图通过提供通信和服务发现协议来解决这个问题。这样,当 A 被编写并且进程 B 实现接口 b 时,只需要存在接口 b。

因此,您可以将 D-Bus 描述为 IPC“管理器”。

从历史上看,命令行界面 (CLI) 工具通常也使用 IPC 管理器,即 shell,通过管道与任意程序进行通信。这种方法的问题在于它不提供数据验证、标准化协议等。因此它只能由高级用户使用。GUI 工具通常应该“隐形”地做到这一点。然而,越来越多的 CLI 工具开始使用 D-Bus,几乎可以作为sudo(1). 因此,您可以作为非特权用户执行systemctl poweroff,它会提示您进行身份验证(这可以与 Windows 上的 UAC 进行比较)。根据您的 polkit 提供商,这甚至可能是一个 GUI 提示。至少在理论上,这种方法更灵活,允许更细粒度的权限,并且无需 setuid 二进制文件(如sudo)。这可以看作是一种安全功能。

当然,作为一种抽象,它引入了某种复杂性(至少在程序的依赖关系方面)。然而,越多的程序(理智地)使用它,它的负担就越小。你是否喜欢 D-Bus 和目前的发展我不能告诉你。但是由于当今计算的更复杂的需求,现代操作系统倾向于在内核之外提供许多关键服务(现在又将历史内核的东西移出,微内核)。所以,如果你“只是”想要一个“简单”的终端,所有这些都可能被认为是“臃肿”,但行业有充分的理由要求它,越来越多的开发人员注意到使用 D-Bus 的好处。它是今天您外壳中旧管道的替代品(不是系统接口,实际上 D-Bus 使用了pipe()等等)。


Sim*_*ter 9

在传统的 Unix 中,运行的程序之间通常很少有通信。每个程序都在完全独立的地址空间中运行,并且只与内核交互。这种模型简单而健壮,但对于桌面环境而言,访问权限大多过于粗糙,并且在许多情况下实现细粒度的访问控制过于复杂。

内核改进访问控制的一个例子是文件系统——非特权程序可以向内核发送写请求,该请求被转换为发送到硬盘的写请求,而不会违反程序之间的分离。然而,这是一个相当复杂的层,对于用户可能想要连接 USB 记忆棒的现代桌面,控制仍然不够好。

对于其他功能,例如声卡访问,内核只实现了一个简单的访问模型:一旦程序访问了声卡,它就可以播放和录制声音,并操纵混音器控件,除了终止程序。

在桌面环境中,我们想要一个更好的模型:浏览器应该只有在询问用户后才能使用麦克风和网络摄像头,当用户退出时,任何正在运行的程序都应该失去麦克风访问权限,但如果用户想要要在一夜之间运行计算,这应该仍然是可能的。

X 窗口系统是在用户程序中执行访问控制的一个很好的先例——通过向另一个程序发送请求来完成对窗口的渲染,该程序计算显示的最终屏幕内容。是否将请求转换为屏幕内容的可见更改取决于当前的访问控制设置:将窗口拉到前面会授予该程序对屏幕空间区域的写访问权限,将其发送到后面会撤销该访问权限。

桌面环境现在提供了许多这样的中介程序,因此对于每个功能都需要一个通信协议和一个打开该程序句柄的方法。

dbus 提供通用协议和代理服务,程序可以在其中请求连接到提供对特定功能的访问控制的程序。如果目标程序已经在运行,broker 只会转发请求,如果它没有运行,broker 会按需启动程序,如果它知道如何做的话。

Windows 上的等效功能是 COM/DCOM 与注册表的结合。


Tsu*_*oku 7

GNOME 的可访问性 API 依赖于它;参见FreeDesktop.org 上的 AT-SPI2。在 D-BUS 之前,即在 GNOME 3 之前,可访问性 API 依赖于CORBA(通用对象请求代理架构),它非常便携,但也比 D-BUS 重。(D-Bus上的AT-SPI页面(存档快照)包含有关此迁移的历史信息。)

可访问性一方面需要应用程序之间的通信,另一方面需要辅助技术之间的通信。例如,盲人计算机用户依赖屏幕阅读器,它可以通过合成语音或盲文(或两者)呈现信息。盲人用户依赖键盘访问应用程序(例如使用 TAB 循环浏览 UI 组件和许多快捷方式);屏幕阅读器需要知道键盘焦点所在的位置,然后查询该 UI 组件的角色(例如“按钮”、“菜单”、“复选框”等)、名称(即它的标签,例如“确定”、“ Cancel”),以及状态和属性(例如,复选框的“选中”和“未选中”,可扩展区域的“扩展”,必需输入字段的“必需”,“禁用”等)。

介绍 ATK、AT-SPI、GAIL 和 GTK+页面上的图表将AT-SPI显示为应用层和辅助技术 (AT) 层之间的层。

Qt也支持 AT-SPI ,从而更容易开发可访问的应用程序。

设置NO_AT_BRIDGE=1(如问题中所述)似乎关闭了辅助技术用于与应用程序通信的桥梁。(见jeffcogswell/org_ally1_bus_fix.md。)