Query System and User Paths with systemd-path
systemd-path is the quiet little tool that stops you hardcoding ~/.config and getting it wrong on someone else's machine. It lists the directories systemd knows about, lets you query one for a script, and tells single directories apart from colon-separated search paths. Allow about ten minutes. Everything here is read-only: no root access, service restart or configuration edit is required.
The route
Jump straight to the step you need, or tick off Done means at the end.
The examples use systemd 255.4-1ubuntu8.17 from the installed systemd package. You need a shell and the systemd-path command.
1. Check the installed command
Confirm which executable is being used and which package supplied it:
$ command -v systemd-path
/usr/bin/systemd-path
$ dpkg-query -W -f='\${Package} \${Version}\n' systemd
systemd 255.4-1ubuntu8.17
The exact package revision will differ on another host. The command also reports the systemd version directly with --version, handy when comparing output between machines:
$ systemd-path --version
systemd 255 (255.4-1ubuntu8.17)
Checkpoint
If command -v finds nothing, stop here and install or repair the package through your normal distribution process. Do not copy a path from another host into a script.
2. List the current system and user paths
With no path name, the command prints every known name and its current value. Use --no-pager so a script, terminal recording or remote session gets the complete output directly:
$ systemd-path --no-pager
temporary: /tmp
system-binaries: /usr/bin
system-configuration: /etc
system-runtime: /run
system-state-logs: /var/log
user-binaries: /home/alice/.local/bin
user-configuration: /home/alice/.config
user-runtime: /run/user/1000
user: /home/alice
search-binaries: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
systemd-system-unit: /usr/lib/systemd/system
systemd-user-unit: /usr/lib/systemd/user
This is representative output, not a portable list. Values depend on the user, architecture, runtime state and distribution layout: user-runtime is tied to the active session, while system-binaries describes a fixed system location.
Checkpoint
Treat the names on the left as the interface and the paths on the right as host-specific data. If a script needs one value, query that name directly rather than parsing this whole listing.
3. Query one directory for a script
Pass one known name after the options. This is the useful form for a deployment check or diagnostic command:
$ systemd-path --no-pager system-configuration
/etc
$ systemd-path --no-pager systemd-system-unit
/usr/lib/systemd/system
Supply a name and the output is the value alone, without the name: label the full listing uses. Capture it as data, not as a command to execute:
config_dir=$(systemd-path --no-pager system-configuration) || exit $?
printf 'system configuration: %s\n' "$config_dir"
The command returns zero on success and non-zero on failure. Keep that status check: a missing or mistyped name must not silently turn into an empty directory variable.
4. Understand search paths
Names beginning with search- behave differently: they are an ordered, colon-separated list, not one directory.
$ systemd-path --no-pager search-binaries-default
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
$ systemd-path --no-pager search-configuration
/home/alice/.config:/etc
Read the result with a path-list tool or shell loop when order matters. Do not join entries with spaces, and do not assume the first directory is writable: a search path is a lookup order, not a permission grant.
search_path=$(systemd-path --no-pager search-binaries-default) || exit $?
old_ifs=$IFS
IFS=:
for directory in $search_path; do
printf 'candidate: %s\n' "$directory"
done
IFS=$old_ifs
That loop is fine for the ordinary absolute directories shown here. If you are handling untrusted input or paths with unusual shell characters, use a language with an explicit path-list parser instead of expanding a variable in the shell.
5. Add a suffix without changing anything
--suffix= appends text to printed paths. It is useful for inspecting a predictable child path, but it does not create the result and does not check that the result exists:
$ systemd-path --no-pager --suffix=/example system-binaries user-binaries
/usr/bin/example
/home/alice/.local/bin/example
Tip
Treat this as formatting, not validation. If the next operation needs a real directory or file, test it separately with test, stat or whatever will consume it. Do not use a suffix to build a path from untrusted text without checking the resulting path's purpose and boundaries.
6. Diagnose a name or version mismatch
A tempting mistake is inventing a name from a phrase in a script. The installed command recognises documented names such as system-binaries and search-binaries-default; similar-looking names are not automatically aliases:
$ systemd-path --no-pager search-paths-default
Path 'search-paths-default' not known.
The exact error text and exit status can vary with the systemd build, so check the status directly when scripting:
if value=$(systemd-path --no-pager system-binaries); then
printf 'system binaries: %s\n' "$value"
else
status=$?
printf 'systemd-path query failed with status %s\n' "$status" >&2
exit "$status"
fi
If two hosts disagree, compare systemd-path --version, the logged-in user, the architecture and the relevant environment. The tool exposes the current machine's paths; it is not a compatibility database for another distribution.
Done means
- Binary confirmed. You checked the installed
systemd-pathbinary and systemd version. - Listing and query both work. You can list paths without a pager and query one named path directly.
- Search paths understood. You know
search-values are ordered, colon-separated lists. - Suffix used correctly.
--suffix=only prints a derived path; you validate it separately when it matters. - Exit status checked. Your scripts check the command's status instead of accepting an empty or mistyped result.