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
。从终结者的手册页,我们看到:
Run Code Online (Sandbox Code Playgroud)--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 &
Run Code Online (Sandbox Code Playgroud)
您将看到第一个命令打开一个新窗口。第二个命令在第一个窗口中打开一个新选项卡。这是由第二个进程使用 dbus 找到第一个进程完成的,要求它打开一个新选项卡,然后退出。
如果您从另一个终端执行此操作:
$ terminator --no-dbus &
$ terminator --new-tab &
Run Code Online (Sandbox Code Playgroud)
您将看到第一个命令打开一个新窗口。第二个命令无法找到第一个窗口的 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
。inotify
在那个 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()
等等)。
在传统的 Unix 中,运行的程序之间通常很少有通信。每个程序都在完全独立的地址空间中运行,并且只与内核交互。这种模型简单而健壮,但对于桌面环境而言,访问权限大多过于粗糙,并且在许多情况下实现细粒度的访问控制过于复杂。
内核改进访问控制的一个例子是文件系统——非特权程序可以向内核发送写请求,该请求被转换为发送到硬盘的写请求,而不会违反程序之间的分离。然而,这是一个相当复杂的层,对于用户可能想要连接 USB 记忆棒的现代桌面,控制仍然不够好。
对于其他功能,例如声卡访问,内核只实现了一个简单的访问模型:一旦程序访问了声卡,它就可以播放和录制声音,并操纵混音器控件,除了终止程序。
在桌面环境中,我们想要一个更好的模型:浏览器应该只有在询问用户后才能使用麦克风和网络摄像头,当用户退出时,任何正在运行的程序都应该失去麦克风访问权限,但如果用户想要要在一夜之间运行计算,这应该仍然是可能的。
X 窗口系统是在用户程序中执行访问控制的一个很好的先例——通过向另一个程序发送请求来完成对窗口的渲染,该程序计算显示的最终屏幕内容。是否将请求转换为屏幕内容的可见更改取决于当前的访问控制设置:将窗口拉到前面会授予该程序对屏幕空间区域的写访问权限,将其发送到后面会撤销该访问权限。
桌面环境现在提供了许多这样的中介程序,因此对于每个功能都需要一个通信协议和一个打开该程序句柄的方法。
dbus 提供通用协议和代理服务,程序可以在其中请求连接到提供对特定功能的访问控制的程序。如果目标程序已经在运行,broker 只会转发请求,如果它没有运行,broker 会按需启动程序,如果它知道如何做的话。
Windows 上的等效功能是 COM/DCOM 与注册表的结合。
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。)
归档时间: |
|
查看次数: |
9684 次 |
最近记录: |