A test suite that talks to D-Bus should not touch your real desktop session, and dbus-run-session wraps it in a throwaway bus instead. The child receives its bus address through DBUS_SESSION_BUS_ADDRESS; when the child exits, the bus daemon exits too.
Allow about ten minutes. You need the dbus-run-session command from the dbus-daemon package and a command that can run without elevated privileges. The examples below use the Ubuntu package dbus-daemon version 1.14.10-4ubuntu4.1, with /usr/bin/dbus-run-session. The installed manpage identifies the underlying D-Bus release as 1.14.10. If your PATH selects another copy, check that copy before relying on its version or diagnostics.
Start with read-only checks. No command in this step needs sudo:
$ command -v dbus-run-session
/usr/bin/dbus-run-session
$ dpkg-query -W -f='${Package} ${Version}\n' dbus-daemon
dbus-daemon 1.14.10-4ubuntu4.1
$ /usr/bin/dbus-run-session --version
dbus-run-session 1.14.10
Checkpoint: the path and version should describe the binary you intend to use. The command accepts a program and its arguments, with an optional -- separator. The separator is useful when the child command might otherwise make its options look like options for dbus-run-session.
Run a short shell that prints the address and checks the environment variables that should not leak into the child. This starts a temporary bus but changes no persistent configuration:
$ /usr/bin/dbus-run-session -- sh -c '
printf "address=%s\n" "$DBUS_SESSION_BUS_ADDRESS"
for name in DBUS_SESSION_BUS_PID DBUS_SESSION_BUS_WINDOWID DBUS_STARTER_BUS_TYPE DBUS_STARTER_ADDRESS; do
if printenv "$name" >/dev/null; then
printf "%s=present\n" "$name"
else
printf "%s=absent\n" "$name"
fi
done
'
address=unix:path=/tmp/dbus-...,guid=...
DBUS_SESSION_BUS_PID=absent
DBUS_SESSION_BUS_WINDOWID=absent
DBUS_STARTER_BUS_TYPE=absent
DBUS_STARTER_ADDRESS=absent
The path, GUID and temporary directory name vary. The address should be non-empty, and the four listed variables should be absent even if they were set in the parent environment. If the address is empty, stop here and inspect the daemon error before running a real workload.
To enter a shell whose D-Bus clients use the new session bus, run:
$ /usr/bin/dbus-run-session -- bash
Commands typed at that prompt inherit the temporary bus address. Exit the nested shell with exit or Ctrl-D. The bus daemon then stops with it. This is useful over SSH or on a text console when there is no suitable desktop session bus.
If the wrapper shell should replace the current shell process, use the shell's exec builtin:
$ exec /usr/bin/dbus-run-session -- bash
This affects only the current shell process and its descendants. It is not a system service and does not create a login session. To return to the parent shell, do not use exec; run the first form and then leave the nested shell.
Put the test command after the wrapper. For example:
$ /usr/bin/dbus-run-session -- make check
The test process sees a session bus whether or not the calling environment already had one. This reduces accidental interaction with the user's normal desktop bus, but it does not sandbox files, network access, privileges or processes. A test that talks to a service outside D-Bus can still change real data.
For one small smoke test, ask the child to print the address and return success:
$ /usr/bin/dbus-run-session -- sh -c 'test -n "$DBUS_SESSION_BUS_ADDRESS"; printf "session bus available\n"'
session bus available
Checkpoint: the wrapper's exit status is the child's exit status in the ordinary case. Capture it immediately if a script needs to branch on the result:
$ /usr/bin/dbus-run-session -- sh -c 'exit 7'
$ printf 'child status: %s\n' "$?"
child status: 7
Everything after the program belongs to that program. Quote paths and values that may contain spaces or shell metacharacters:
$ /usr/bin/dbus-run-session -- /usr/bin/printf '%s\n' 'dbus child started'
dbus child started
Do not paste an untrusted string into a shell command. In particular, sh -c interprets its next argument as shell source, so use it only when you control that source. If the program name begins with a dash, or you simply want a visible boundary, place -- before it.
A successful wrapper run does not mean the bus did useful work; it means the child returned success. The wrapper returns the child's status, returns 0 for --help and --version, and uses 127 for an error in dbus-run-session itself. If the child is killed by signal number n, the wrapper reports 128 plus n. This distinction matters in CI logs.
Reproduce a missing-program error without changing anything:
$ /usr/bin/dbus-run-session -- /path/to/program-that-does-not-exist
$ printf 'wrapper status: %s\n' "$?"
wrapper status: 127
The exact diagnostic is system-dependent. Check the program path, executable permission and PATH before adding privileges. Running this command as root will not make a missing executable appear.
By default, the wrapper searches PATH for an executable named dbus-daemon. Use --dbus-daemon=/absolute/path/to/dbus-daemon only when you have verified a specific daemon binary is required. An absolute path avoids a later PATH change selecting a different binary:
$ /usr/bin/dbus-run-session --dbus-daemon=/usr/bin/dbus-daemon -- /usr/bin/true
$ printf 'status: %s\n' "$?"
status: 0
--config-file=FILENAME passes a custom configuration file to the daemon instead of the normal --session argument. This is a configuration change with security and connectivity consequences, not a troubleshooting switch. Before using it, read the file, confirm its ownership and permissions, and test it with a harmless child. Do not overwrite a system configuration file for this experiment, and do not use sudo unless the chosen file genuinely requires protected access.
/usr/bin/dbus-run-session reports the expected installed release.DBUS_SESSION_BUS_ADDRESS.-- boundary.