Cogs and Levers A blog full of technical stuff

D-Bus

Introduction

D-Bus (Desktop Bus) is an inter-process communication (IPC) system used on Linux and other Unix-like systems. It allows different programs — even running as different users — to send messages and signals to each other without needing to know each other’s implementation details.

Main ideas

  • Message bus: A daemon (dbus-daemon) runs in the background and acts as a router for messages between applications.
  • Two main buses:
    • System bus – for communication between system services and user programs (e.g., NetworkManager, systemd, BlueZ).
    • Session bus – for communication between applications in a user’s desktop session (e.g., a file manager talking to a thumbnailer).
  • Communication model:
    • Method calls – like function calls between processes.
    • Signals – broadcast events (e.g., “Wi-Fi disconnected”).
    • Properties – read/write state values.
  • Naming:
    • Bus names – unique or well-known IDs for services (e.g., org.freedesktop.NetworkManager).
    • Object paths – hierarchical paths (e.g., /org/freedesktop/NetworkManager).
    • Interfaces – namespaces for methods/signals (e.g., org.freedesktop.NetworkManager.Device).

Here’s a visual representation of the architecture:

flowchart LR subgraph AppLayer[User Applications] A1[App 1] A2[App 2] end subgraph DBusDaemon[D-Bus Daemon Message Bus] D1[System Bus] D2[Session Bus] end subgraph SysServices[System Services] S1[NetworkManager] S2[BlueZ Bluetooth] S3[systemd-logind] end %% Connections A1 --method calls or signals--> D2 A2 --method calls or signals--> D2 S1 --method calls or signals--> D1 S2 --method calls or signals--> D1 S3 --method calls or signals--> D1 %% Cross communication D1 <-->|routes messages| A1 D1 <-->|routes messages| A2 D2 <-->|routes messages| A1 D2 <-->|routes messages| A2 %% System bus to service connections D1 <-->|routes messages| S1 D1 <-->|routes messages| S2 D1 <-->|routes messages| S3

User applications call methods or raise signals to a Session Bus inside the D-Bus Daemon. In turn, these messages are routed to System Services, with responses sent back to the applications via the bus.

D-Bus removes the need for each program to implement its own custom IPC protocol. It’s widely supported by desktop environments, system services, and embedded Linux stacks.

In this article, we’ll walk through some basic D-Bus usage, building up to a few practical use cases.

busctl

busctl lets you interact with D-Bus from the terminal. According to the man page:

busctl may be used to introspect and monitor the D-Bus bus.

We can start by listing all connected peers:

busctl list

This shows a list of service names for software and services currently on your system’s bus.

Devices

If you have NetworkManager running, you’ll see org.freedesktop.NetworkManager in the list.
You can query all available devices with:

busctl call org.freedesktop.NetworkManager /org/freedesktop/NetworkManager \
  org.freedesktop.NetworkManager GetDevices

Example output:

ao 6 "/org/freedesktop/NetworkManager/Devices/1" "/org/freedesktop/NetworkManager/Devices/2" "/org/freedesktop/NetworkManager/Devices/3" "/org/freedesktop/NetworkManager/Devices/4" "/org/freedesktop/NetworkManager/Devices/5" "/org/freedesktop/NetworkManager/Devices/6"
What is ao 6? At the start of the output, you'll see the data type. An array of object paths with 6 elements.

Those object paths aren’t very descriptive, so you can query one for its interface name:

busctl get-property org.freedesktop.NetworkManager \
  /org/freedesktop/NetworkManager/Devices/1 \
  org.freedesktop.NetworkManager.Device Interface

On my system:

s "lo"

The leading s tells us this is a string — here, the loopback adapter.

Introspect

You can list all properties, methods, and signals for a given object with:

busctl introspect org.freedesktop.NetworkManager \
  /org/freedesktop/NetworkManager/Devices/1

Or without the pager:

busctl --verbose --no-pager introspect org.freedesktop.NetworkManager \
  /org/freedesktop/NetworkManager/Devices/1

Desktop Notifications

Now that we can query D-Bus, we can also send messages.
For example, you could end a shell script with a visual notification on your desktop:

gdbus call --session \
  --dest org.freedesktop.Notifications \
  --object-path /org/freedesktop/Notifications \
  --method org.freedesktop.Notifications.Notify \
  "my-app" 0 "" "Build finished" "All tests passed" \
  '[]' '{"urgency": <byte 1>}' 5000

Tip: gdbus is part of the glib2 or glib2-tools package on many distributions.

This performs a method call on a D-Bus object.

  • --dest — The bus name (service) to talk to.
  • --object-path — The specific object inside that service.
  • --method — The method we want to invoke.

This method’s signature is s u s s s as a{sv} i, meaning:

Code Type Description Example Value Meaning
s string "my-app" Application name
u uint32 0 Notification ID (0 = new)
s string "" Icon name/path
s string "Build finished" Title
s string "All tests passed" Body text
as array of strings '[]' Action identifiers
a{sv} dict<string, variant> '{"urgency": <byte 1>}' Hints (0=low, 1=normal, 2=critical)
i int32 5000 Timeout (ms)

Monitoring

D-Bus also lets you watch messages as they pass through.
To monitor all system bus messages (root may be required):

busctl monitor --system

To filter for a specific destination:

busctl monitor org.freedesktop.NetworkManager

These commands stream events to your console in real time.

Conclusion

D-Bus is a quiet but powerful layer in modern Linux desktops and servers. Whether you’re inspecting running services, wiring up automation, or building new desktop features, learning to speak D-Bus gives you a direct line into the heart of the system. Once you’ve mastered a few core commands, the rest is just exploring available services and imagining what you can automate next.