
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 &
最初のコマンドで新しいウィンドウが開きます。2 番目のコマンドで最初のウィンドウに新しいタブが開きます。これは、2 番目のプロセスが dbus を使用して最初のプロセスを見つけ、新しいタブを開くように要求し、終了することによって実行されます。
別の端末からこれを行う場合:
$ terminator --no-dbus &
$ terminator --new-tab &
最初のコマンドで新しいウィンドウが開くことがわかります。2 番目のコマンドは最初のウィンドウの dbus を見つけられないため、新しいウィンドウを起動します。これをテストするために terminator をインストールしましたが、これは本当です。
さらに、polkit も影響を受けると思われます。Polkit は dbus を使用して GUI アプリケーションの権限を昇格します。これはsudo
GUI の世界の のようなものです。gnome で、管理者のパスワードを要求されているときに画面全体が覆われるのを確認した場合、それは polkit が動作している状態です。terminator
があれば、起動するどの GUI アプリケーションでもそのプロンプトは表示されないと思われます--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
パス/org/freedesktop/systemd1/unit/foo_2eservice
とメンバーを持つインターフェースのファイル記述子を取得できますPropertiesChanged
。その FD に を設定するinotify
と、サービスの開始、停止、失敗などに反応する方法が突然得られます。
ssh.service
特定のユニット (つまり)の systemd dbus で何が利用可能かを確認したい場合は、次のコマンドを試してください。
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
D-Bus については @Stewart による詳細な回答がすでにありますが、私は D-Bus の設計に関する高レベルのアイデアを加えてそれを修正したいと思います。
UNIX および Linux システムにおけるプロセス間通信 (IPC) の「従来の」方法では、ソケットを直接使用します。たとえば、プロセス A がオープンし/var/run/a.socket
、プロセス B がそれに対して読み取り/書き込みを行います。これは、相互に通信するように設計された緊密に結びついたプログラムでは、かなりうまく機能します。
ただし、プログラム A の作成時にプログラム B が存在しなかった場合でも、2 つのプログラムのプロセス間で通信を行う必要がある場合があります。D-Bus は、通信とサービス検出のプロトコルを提供することでこの問題を解決しようとします。この方法では、A の作成時にインターフェイス b のみが存在する必要があり、プロセス B はインターフェイス b を実装します。
したがって、D-Bus は IPC「マネージャー」として説明できます。
歴史的に、コマンドライン インターフェイス (CLI) ツールは通常、IPC マネージャーであるシェルを使用して、パイプを使用して任意のプログラムと通信します。このアプローチの問題は、データ検証、標準化されたプロトコルなどが提供されないことです。したがって、パワー ユーザーのみが使用できます。GUI ツールは一般に、これを「目に見えない形で」行う必要があります。ただし、ますます多くの CLI ツールが、 の代わりとして D-Bus を使用し始めていますsudo(1)
。したがって、権限のないユーザーとして を実行するsystemctl poweroff
と、認証を求めるプロンプトが表示されます (これは、Windows の UAC に相当します)。polkit プロバイダーによっては、これが GUI プロンプトになることもあります。少なくとも理論上は、このアプローチの方が柔軟性が高く、よりきめ細かい権限を許可し、setuid バイナリ ( などsudo
) なしで動作します。これはセキュリティ機能と見なすことができます。
もちろん、抽象化として、ある種の複雑さがもたらされます (少なくともプログラムの依存関係において)。しかし、より多くのプログラムが (まともな) それを利用すればするほど、負担は少なくなります。D-Bus と現在の開発が気に入るかどうかは私にはわかりません。しかし、現代のオペレーティング システムは、今日のコンピューティングのより複雑な要件のために、カーネルの外部で多くの重要なサービスを提供する傾向があります (そして今では、歴史的なカーネルのものを再びマイクロカーネルのように外部に移動しています)。したがって、「単に」「シンプルな」端末が欲しいだけなら、これらすべてが「肥大化」と見なされるかもしれませんが、業界がそれを要求するのには十分な理由があり、ますます多くの開発者が D-Bus を使用する利点に気づいています。これは、シェル内の古き良きパイプ (システム インターフェイスではありません。実際には D-Bus は、pipe()
などを使用します) の今日の代替品です。
答え3
従来の Unix では、実行中のプログラム間の通信は通常ほとんどありません。すべてのプログラムは完全に独立したアドレス空間で実行され、カーネルとのみ対話します。このモデルはシンプルで堅牢ですが、アクセス許可はデスクトップ環境には粗すぎる場合が多く、きめ細かいアクセス制御を実装するのは多くの場合複雑すぎます。
カーネルがアクセス制御を改良する例の 1 つはファイル システムです。権限のないプログラムはカーネルに書き込み要求を送信でき、この要求はプログラム間の分離を侵害することなくハードディスクに送信される書き込み要求に変換されます。ただし、これはかなり複雑なレイヤーであり、ユーザーが USB スティックを接続する可能性のある最新のデスクトップでは、制御はまだ十分ではありません。
その他の機能、たとえばサウンド カード アクセスの場合、カーネルは単純なアクセス モデルのみを実装します。プログラムがサウンド カードにアクセスすると、サウンドの再生や録音、ミキサー コントロールの操作が可能になりますが、プログラムを終了する以外にそのアクセスを取り消すメカニズムはありません。
デスクトップ環境では、より細かいモデルが必要になります。ブラウザは、ユーザーに確認した後でのみマイクとウェブカメラを使用でき、ユーザーがログアウトすると、実行中のプログラムはマイクにアクセスできなくなりますが、ユーザーが夜間に計算を実行したい場合は、それが可能である必要があります。
X ウィンドウ システムは、ユーザー プログラムでアクセス制御を実行するための良い前例です。ウィンドウへのレンダリングは、表示される最終的な画面コンテンツを計算する別のプログラムに要求を送信することによって行われます。要求が画面コンテンツの目に見える変更に変換されるかどうかは、現在のアクセス制御設定に基づいて決定されます。ウィンドウを前面に引っ張ると、このプログラムに画面領域への書き込みアクセスが与えられ、ウィンドウを背面に送ると、そのアクセスが取り消されます。
現在、デスクトップ環境ではこのようなメディエーター プログラムが多数提供されているため、各機能ごとに通信プロトコルとそのプログラムへのハンドルを開く方法が必要です。
dbus は、汎用プロトコルと、特定の機能へのアクセス制御を提供するプログラムへの接続をプログラムが要求できるブローカー サービスを提供します。対象のプログラムがすでに実行されている場合、ブローカーは要求を転送するだけです。まだ実行されていない場合、ブローカーは、その方法がわかっている場合は、要求に応じてプログラムを起動します。
Windows での同等の機能は、レジストリと組み合わせた COM/DCOM です。
答え4
- 私は有効にする隠す壊れるはずです
dbus
。 - 私もユニークなものを変える
machine-id
(dbus
起動時に毎回生成されるrc.local
devuanも起動ごとに生成します)
XFCEでもすべて動作するようです(gnomeなどの一部のデスクトップではより依存するdbus
)。私はアプリを消防署したがって、想定されるセキュリティ上の利点が失われることは、dbus
実際には問題ではありません。
以下の Linux ディストリビューションはdbus
& がなくても問題なく動作するようですsystemd
:
小さな問題はありますが、十分な能力があれば簡単に解決できます。