You forgot the export
in your .env file, so the variable isn't actually an environment variable.
Shell variables are not exported to environment by default. Only assignments to an already exported variable will be re-exported automatically; if XDG_RUNTIME_DIR
is a brand new variable, it will become a shell internal variable unless you use the export
or declare -x
builtins. (Or unless the "allexport" shell option is enabled, but using it in .bashrc has some weird gotchas.)
echo $FOO
"sees" the variable because the expansion of $FOO in command-line is done by the shell interpreter itself, not by the command – 'echo' doesn't have to access the environment at all, whereas 'systemctl' does.
Instead of echo, you could use declare -p FOO
to have the shell itself tell you the variable's state (including showing the x
flag if the variable is exported), or use env
or printenv
to see what the environment looks like from the point of view of an external process (non-exported shell variables simply won't show up here).
Either way, you should never need to do this for interactive logins. This specific variable is supposed to be put in your environment through PAM (by pam_systemd) as soon as you log in – even before your shell is run.
For scripts that need to access another user's services, systemctl --user -M ${USER}@.host
will make systemctl itself find the specified user's runtime directory and the D-Bus socket.