
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
:
會有一些小問題,但如果你有足夠的能力,這些問題很容易解決。