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
NO_AT_BRIDGE=1
我通过添加到 摆脱了上述错误/etc/environment
。我不知道那是做什么的。
几乎所有 GUI 应用程序似乎都与dbus
.有些允许在没有 的情况下启动dbus
,即:
terminator --no-dbus
我认为行为没有什么不同。什么应该停止工作,什么时候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
据我所知,一切都一样。上述脚本的目的是什么?
在什么情况下,我的应用程序通过 相互通信会有用dbus
?
是否有一些应用程序没有 就无法运行dbus
?
我的系统是 Debian Buster,我使用的是普通的 openbox 环境(没有任何桌面环境,如 Gnome 或 KDE)
答案1
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.
因此,如果您从另一个终端(konsole、xterm、gnome-terminal)执行此操作:
$ terminator &
$ terminator --new-tab &
您将看到第一个命令打开一个新窗口。第二个命令在第一个窗口中打开一个新选项卡。这是由第二个进程使用 dbus 查找第一个进程,要求它打开一个新选项卡,然后退出来完成的。
如果您从另一个终端执行此操作:
$ terminator --no-dbus &
$ terminator --new-tab &
您将看到第一个命令打开一个新窗口。第二个命令无法找到第一个窗口的 dbus,因此它启动一个新窗口。我安装了终结者来测试这一点,这是真的。
此外,我怀疑 polkit 也会受到影响。 Polkit 使用 dbus 来提升 GUI 应用程序的权限。这就像sudo
GUI 世界的一样。如果您在 gnome 中,并且在要求您输入管理员密码时看到整个屏幕被覆盖,这就是 polkit 的作用。我怀疑terminator
如果您有--no-dbus
.它要么无法进行身份验证,要么回退到某些终端身份验证。从terminator
尝试pkexec ls
。这将以ls
提升的权限运行。看看使用和不使用该选项是否有所不同--no-dbus
。我的窗口管理器(i3)中没有 polkit 代理,所以我无法测试这个代理。
我主要了解 systemd 方面的 dbus,所以这就是我其余答案的来源。
是否有一些应用程序没有 就无法运行
dbus
?
是的。拿systemctl
。 systemctl status
将向 发出查询"org.freedesktop.systemd1"
,并将其呈现给您。 systemctl start
将调用 dbus 方法并将单位作为参数传递给该方法。 systemd
接听电话并执行操作。
如果您想采取行动来响应 systemd 单元(即 foo.service)更改状态,您可以获取org.freedesktop.DBus.Properties
带有 path/org/freedesktop/systemd1/unit/foo_2eservice
和 member 的接口的文件描述符PropertiesChanged
。在那个 FD 上设置一个inotify
,你突然就有了一种方法来对服务的启动、停止、失败等做出反应。
如果您想查看 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 false const
.SubState property s "running" emits-change
.SuccessAction property s "none" const
.SuccessActionExitStatus property i -1 const
.Transient property b false const
.TriggeredBy property as 0 const
.Triggers property as 0 const
.UnitFilePreset property s "enabled" -
.UnitFileState property s "enabled" -
.WantedBy property as 1 "multi-user.target" const
.Wants property as 0 const
由此可见dbus接口的功能相当强大。
您可能会问:为什么这些应用程序不通过套接字或文件进行通信?
DBus 提供了一个通用接口。您不需要根据正在交谈的应用程序使用不同的逻辑来调用方法或检查属性。您只需要知道路径的名称即可。
我用它systemd
作为例子,因为这是我最理解的,但在大多数桌面上都有大量 dbus 的用途。从身份验证到显示设置的所有内容都可以在 dbus 上使用。
答案2
@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 的优点。它是当今 shell 中旧管道的替代品(不是系统接口,实际上 D-Bus 使用pipe()
等)。
答案3
在传统的 Unix 中,正在运行的程序之间通常很少有通信。每个程序都在完全独立的地址空间中运行,并且仅与内核交互。这种模型简单而健壮,但访问权限对于桌面环境来说大多过于粗略,并且在许多情况下实现细粒度的访问控制过于复杂。
内核改进访问控制的一个例子是文件系统——非特权程序可以向内核发送写请求,该请求会被转换为发送到硬盘的写请求,而不会违反程序之间的隔离。不过,这是一个相当复杂的层,对于用户可能想要连接 USB 记忆棒的现代桌面来说,控制仍然不够精细。
对于其他功能,例如声卡访问,内核仅实现了一个简单的访问模型:一旦程序访问了声卡,它就可以播放和录制声音,以及操作混音器控制,并且没有任何机制可以撤销该访问权限,除了终止程序。
在桌面环境中,我们想要一个更好的模型:浏览器应该只有在询问用户后才能够使用麦克风和网络摄像头,并且当用户注销时,任何正在运行的程序都应该失去麦克风访问权限,但如果用户想要整夜运行计算,这应该仍然是可能的。
X 窗口系统是在用户程序中执行访问控制的良好先例——通过向另一个程序发送请求来计算显示的最终屏幕内容来完成对窗口的渲染。请求是否转换为屏幕内容的可见更改取决于当前的访问控制设置:将窗口拉到前面可为该程序提供对屏幕空间区域的写访问权限,将其发送到后面则撤销该访问权限。
桌面环境现在提供了大量此类中介程序,因此对于每个功能都需要有一个通信协议和一种打开该程序句柄的方法。
dbus 提供通用协议和代理服务,其中程序可以请求连接到提供对特定功能的访问控制的程序。如果目标程序已经在运行,代理将仅转发请求,如果尚未运行,代理将根据需要启动该程序(如果它知道如何启动)。
Windows 上的等效功能是 COM/DCOM 与注册表的组合。
答案4
- 我启用隐藏的这应该会打破
dbus
。 - 我也改变独特的
machine-id
dbus
每次启动时都会生成rc.local
(devuan 也会在每次启动时生成它)
一切似乎仍然可以在 XFCE 下工作(某些桌面,例如 gnome 可能是更依赖于dbus
)。我通过运行应用程序消防监狱因此,失去任何所谓的安全利益dbus
并不是真正的问题。
dbus
以下 Linux 发行版在没有& 的情况下似乎运行良好systemd
:
会有一些小问题,但如果你有足够的能力,这些问题很容易解决。