3

Systemd has a flag --global, on my distribution, Ubuntu, I'm finding a catch-22.

  • If I run it as an unprivileged user, systemctl will not have the proper permissions to copy the unit file into /etc.
  • It won't work via sudo, as sudo fails to set up the $DBUS_SESSION_BUS_ADDRESS and the $XDG_* variables.

It may or may not work via sudo -E, which preserves the environment. It definitely works if running from a root session (e.g. from a virtual console).

What is the proper way to use systemctl --global?

Evan Carroll
  • 30,763
  • 48
  • 183
  • 315
usretc
  • 629

1 Answers1

2

--global: When used with enable and disable, operate on the global user configuration directory, thus enabling or disabling a unit file globally for all future logins of all users.

The systemctl --global flag references systemctl --user services on a "global" level, and is mainly used to enable/disable user units for all users on the system.

In contrast to systemctl --system units, enabled --global units do not start until an individual user logs in and thus "wants" the user unit. (Note that sudo/su do not "log in" a user in this sense; see below for alternatives.)

If you look at the systemd user unit search path, you'll notice that it contains some "global" directories which are not writeable by non-root users. Units in these directories can either be managed by sudo systemctl --global (for all users) or systemctl --user (for an individual user).

ls -l /usr/lib/systemd/user

ls -l /etc/systemd/user

Using sudo systemctl --global is limited to managing the units as files, primarily enabling/disabling them. Manually enabling a user unit globally will symlink it under targets/wants directories in /etc/systemd/user; for individual users it's ~/.config/systemd/user.

ls -l ~/.config/systemd/user

On a desktop system, there can be quite a few global user units available, possibly enabled by default during (package) installation. The list of units "in memory" also includes generated and transient units/"files", such as devices and scopes. Use, for example, --type service to narrow it down.

systemctl --global list-unit-files
systemctl --global list-units

systemctl --global list-units --all

While the list of --global user unit files may look very similar to that of an individual --user, the latter includes (non-global) user-specific directories in the search path. See also user.conf, where additional user directories can be configured.

systemctl --user list-units
systemctl --user list-unit-files

For a "live" list of unit search directories, including custom user.conf additions for the current user, use systemctl show.

systemctl --user show --property 'UnitPath' --value

(Just noted that while systemctl --global list-unit-files excludes those in ~/.config/systemd/user, systemctl --global list-units includes them. Seems incorrect, or at least inconsistent?)


As user units do not load/execute until a user logs in, they have no --global status. You can instead look at the unit status for each individual logged in user, both yourself and others.

Since sudo/su doesn't actually perform a "proper log in" from systemd's view, it shouldn't be used to manage units of other users. Instead, have a look at --machine, where @ and .host can be used to refer to the current system: sudo systemctl --user --machine otheruser@.host.

# NOTE: demo status for yourself, but via sudo.
sudo systemctl --user --machine "${USER}@.host" status

To instead "log in" as another user, as a separate session with all the DBus etcetera facilities in place, use machinectl to start a shell. (Note that machinectl login will also start a shell, but as a more cumbersome "manual" login process.)

# NOTE: demo logging in as yourself, but with a custom/different login shell.
sudo machinectl shell "${USER}@.host" /bin/sh

See also loginctl, and in particular enable-linger which allows long-running --user services without having to log in "manually".