Starting A DBus Session Application from systemd User Mode
Solution 1
You may find some help in the ArchLinux wiki page which discusses setting the environment for user Units. In particular,
systemctl --user import-environment
will export all the current environment variables into your systemd user environment. You can provide an explicit list of variables instead. You can check by running
systemctl --user show-environment
before and after. There is also
systemctl --user set-environment MYVAR=myvalue ...
systemctl --user unset-environment MYVAR ...
See the systemctl
man page.
The wiki also mentions a dbus specific alternative with which I had less success:
dbus-update-activation-environment --systemd --all
Solution 2
My solution takes into account @meuh's solution above and some digging.
Step one is to create a dummy user unit called dbus-environment.service
:
[Unit]
Description=Environment Imported Target
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
Next step is to create a Bash script:
#!/bin/bash
systemctl --user import-environment
systemctl --user start dbus-environment.service
Next, add this script to your window manager's startup applications which are guaranteed to run within the DBUS session and the window manager, X, etc.
On session login, the script will be called, importing everything into the systemd user daemon.
Next, for all units depending on these environment variables, simply have them depend on dbus-environment.service
:
[Unit]
Description=Duplicity Backup Service
Requires=dbus-environment.service
After=dbus-environment.service
[Service]
Type=oneshot
ExecStart=/home/naftuli/.local/bin/duply home backup
At this point, when this service starts, it is guaranteed to have the environment imported. Perhaps I should be using a target rather than a service, but that exercise will have to wait.
Related videos on Youtube
Naftuli Kay
Updated on September 18, 2022Comments
-
Naftuli Kay over 1 year
I have a simple need to run a systemd user service with access to all of the environment variables provided by the user DBus session. Here's my example unit:
[Unit] Description=Environment Demo [Service] Type=simple Environment=DISPLAY=:0 ExecStart=/bin/bash -c 'env > shell.env.sh' Restart=on-failure RestartSec=5s StandardOutput=journal StandardError=journal [Install] WantedBy=default.target
The keys exported are:
_ DISPLAY HOME LANG LOGNAME MANAGERPID PATH PWD SHELL SHLVL USER XDG_RUNTIME_DIR
This is a far cry from the full list of environment variables present if I launch a desktop application from my tray or from my launcher (I'm on elementary OS Loki aka Ubuntu 16.04 xenial). If I launch my terminal emulator (
pantheon-terminal
) and I get a sorted list of my environment variables, I get the following:_ DBUS_SESSION_BUS_ADDRESS DEFAULTS_PATH DESKTOP_SESSION DISPLAY EDITOR GDM_LANG GDMSESSION GIO_LAUNCHED_DESKTOP_FILE GIO_LAUNCHED_DESKTOP_FILE_PID GNOME_DESKTOP_SESSION_ID GPG_TTY GSETTINGS_SCHEMA_DIR GTK_CSD GTK_MODULES HOME LANG LANGUAGE LESSCLOSE LESSOPEN LOGNAME LS_COLORS MANDATORY_PATH PANTHEON_TERMINAL_ID PATH PROMPT_COMMAND PWD QT_ACCESSIBILITY QT_IM_MODULE QT_LINUX_ACCESSIBILITY_ALWAYS_ON QT_STYLE_OVERRIDE SESSION_MANAGER SHELL SHLVL SSH_AGENT_PID SSH_AUTH_SOCK TERM USER VTE_VERSION XAUTHORITY XDG_CONFIG_DIRS XDG_CURRENT_DESKTOP XDG_DATA_DIRS XDG_GREETER_DATA_DIR XDG_MENU_PREFIX XDG_RUNTIME_DIR XDG_SEAT XDG_SEAT_PATH XDG_SESSION_DESKTOP XDG_SESSION_ID XDG_SESSION_PATH XDG_SESSION_TYPE XDG_VTNR XMODIFIERS
To make things more clear:
diff --git a/systemd-user.env.txt b/pantheon-terminal.env.txt index c684056..f6d0685 100644 --- a/systemd-user.env.txt +++ b/pantheon-terminal.env.txt @@ -1,12 +1,54 @@ _ +DBUS_SESSION_BUS_ADDRESS +DEFAULTS_PATH +DESKTOP_SESSION DISPLAY +EDITOR +GDM_LANG +GDMSESSION +GIO_LAUNCHED_DESKTOP_FILE +GIO_LAUNCHED_DESKTOP_FILE_PID +GNOME_DESKTOP_SESSION_ID +GPG_TTY +GSETTINGS_SCHEMA_DIR +GTK_CSD +GTK_MODULES HOME LANG +LANGUAGE +LESSCLOSE +LESSOPEN LOGNAME -MANAGERPID +LS_COLORS +MANDATORY_PATH +PANTHEON_TERMINAL_ID PATH +PROMPT_COMMAND PWD +QT_ACCESSIBILITY +QT_IM_MODULE +QT_LINUX_ACCESSIBILITY_ALWAYS_ON +QT_STYLE_OVERRIDE +SESSION_MANAGER SHELL SHLVL +SSH_AGENT_PID +SSH_AUTH_SOCK +TERM USER +VTE_VERSION +XAUTHORITY +XDG_CONFIG_DIRS +XDG_CURRENT_DESKTOP +XDG_DATA_DIRS +XDG_GREETER_DATA_DIR +XDG_MENU_PREFIX XDG_RUNTIME_DIR +XDG_SEAT +XDG_SEAT_PATH +XDG_SESSION_DESKTOP +XDG_SESSION_ID +XDG_SESSION_PATH +XDG_SESSION_TYPE +XDG_VTNR +XMODIFIERS
There are somewhere around 30 more environment variables when starting something this way.
My use case is this: I want to be able to start processes with a full environment like in the context of launching my terminal application.
How can I expose a full(er) environment to my systemd user daemons?
-
Jack O'Connor over 6 yearsOP might also want to look at
~/.config/environment.d
. See unix.stackexchange.com/a/403196/23305. -
Naftuli Kay almost 6 yearsThat would not solve it. The current execution context is systemd, which doesn't have the display manager environment variables. Executing a shell will not have it automatically inherit these environment variables. You need something that is guaranteed to inherit these variables, so a normal shell won't have them.
-
Robin almost 6 yearsThanks! I am a newbie. Still trying to understand systemd. I am actually also stuck in a similar situation where in I would like to import all environment variable available to the user to the system service daemon.. There is no possibility for me to use a script to import these variables. Have you come across another solution so that all the variables which have been set for the users becomes visible to service daemon? Thanks!
-
Naftuli Kay almost 6 yearsdbus-launch might be able to do something. I was originally crawling the /proc/PID/env of the dbus session to get its address and then call dbus-launch