
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 모드에서 관리자 비밀번호를 입력하라는 메시지가 표시되는 동안 전체 화면이 가려지는 경우 이는 폴킷이 작동 중인 것입니다. .terminator
--no-dbus
인증에 실패하거나 일부 터미널 인증으로 대체됩니다. terminator
시도 에서 pkexec ls
. ls
높은 권한으로 실행됩니다 . 옵션 이 있는 것과 없는 것이 다른지 확인해보세요 --no-dbus
. 내 창 관리자(i3)에 polkit 에이전트가 없으므로 이것을 테스트할 수 없습니다.
나는 주로 systemd 측면에서 dbus에 대해 알고 있으므로 나머지 대답은 여기에서 나옵니다.
없이는 작동하지 않는 응용 프로그램이 있습니까
dbus
?
예. 가져가다 systemctl
. systemctl status
에 대한 쿼리를 발행 "org.freedesktop.systemd1"
하고 이를 귀하에게 제시할 것입니다. systemctl start
dbus 메소드를 호출하고 유닛을 해당 메소드에 대한 인수로 전달합니다. 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(Inter Process Communication)의 "전통적인" 방식은 소켓을 직접 사용합니다. 예를 들어 프로세스 A가 열리고 /var/run/a.socket
프로세스 B가 소켓을 읽고 씁니다. 이는 함께 통신하도록 설계된 긴밀하게 짜여진 프로그램에 적합합니다.
그러나 프로그램 A가 작성될 때 프로그램 B가 존재하지 않았던 두 프로그램의 프로세스 간에 통신을 원할 수도 있습니다. D-Bus는 통신 및 서비스 검색을 위한 프로토콜을 제공하여 이 문제를 해결하려고 시도합니다. 이렇게 하면 A가 작성되고 프로세스 B가 인터페이스 b를 구현하는 경우 인터페이스 b만 존재하면 됩니다.
따라서 D-Bus를 IPC "관리자"로 설명할 수 있습니다.
역사적으로 명령줄 인터페이스(CLI) 도구는 일반적으로 IPC 관리자인 셸을 사용하여 파이프를 통해 임의의 프로그램과 통신합니다. 이 접근 방식의 문제점은 데이터 검증, 표준화된 프로토콜 등을 제공하지 않는다는 것입니다. 따라서 고급 사용자만 사용할 수 있습니다. 일반적으로 GUI 도구는 이 작업을 "눈에 보이지 않게" 수행해야 합니다. 그러나 점점 더 많은 CLI 도구가 .NET 대신 D-Bus를 사용하기 시작합니다 sudo(1)
. 따라서 권한이 없는 사용자로서 실행하면 systemctl poweroff
인증을 묻는 메시지가 표시됩니다(Windows의 UAC와 비교할 수 있음). 폴킷 제공업체에 따라 이는 GUI 프롬프트일 수도 있습니다. 적어도 이론적으로 이 접근 방식은 더 유연하고 더 세분화된 권한을 허용하며 setuid 바이너리(예: sudo
) 없이 작동합니다. 이는 보안 기능으로 볼 수 있습니다.
물론 추상화로 인해 일종의 복잡성이 발생합니다(적어도 프로그램의 종속성 측면에서는). 그러나 더 많은 프로그램이 이를 (제대로) 사용할수록 부담은 줄어듭니다. 당신이 D-Bus와 현재 개발을 좋아하는지 여부는 말씀드릴 수 없습니다. 그러나 최신 운영 체제는 오늘날 컴퓨팅의 더 복잡한 요구 사항으로 인해 커널 외부에서 많은 중요한 서비스를 제공하는 경향이 있습니다(이제 과거 커널 항목을 다시 마이크로커널 방식으로 이동). 따라서 "간단한" 터미널을 "그냥" 원한다면 이 모든 것이 "부풀어오르는" 것으로 간주될 수 있지만 업계에서는 그럴 만한 이유가 있어 이를 요구하고 있으며 점점 더 많은 개발자들이 D-Bus 사용의 장점에 주목하고 있습니다. 이는 쉘의 오래되고 좋은 파이프를 오늘날 대체하는 것입니다(시스템 인터페이스가 아니라 실제로 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
.
사소한 문제가 있을 수 있지만 합리적으로 유능하다면 쉽게 해결할 수 있습니다.