EnvironmentFile
is not an option as per this answer.
I am trying to understand the recommended way of using and passing environment variables.
I have a urxvtd.socket
:
[Unit]
Description=urxvt deamon (socket activation)
Documentation=man:urxvtd(1) man:urxvt(1)
[Socket]
ListenStream=%t/urxvt/urxvtd-%H
[Install]
WantedBy=sockets.target
Now a urxvtd.service
with a Requires
dependency on that urxvtd.socket:
[Unit]
Description=Urxvt Terminal Daemon
Requires=urxvtd.socket
[Service]
# Needs to know socket file location RXVT_SOCKET environment variable.
# Where will it come from?
ExecStart=/usr/bin/urxvtd -o -q
[Install]
WantedBy=default.target
Now I need RXVT_SOCKET
to be set before starting i3 as i3 will have a key binding to start urxvtc
(urxvt client).
If I start i3/Xorg without systemd (i.e with xinitrc), and put in .zshenv
(user specific environment file loaded always.):
export RXVT_SOCKET=${XDG_RUNTIME_DIR}/urxvt/urxvtd-machinename
Then urxvtc
launched by i3 will correctly infer the RXVT_SOCKET variable and look for the socket at that path.
However, the urxvtd.service
launches urxvtd
(the daemon), so it also needs RXVT_SOCKET.
The Archwiki recommends setting the environment in urxvtd.service
:
...
Environment=RXVT_SOCKET=%t/urxvtd-%H
...
But therein the problem lies. Why should the environment variable be set again in urxvtd.service
, when the initial user urxvtd.socket
should set it?
Note, it is set again in .zshenv
for i3 to get it. This is a case of multiple sources of truth for one simple environment variable..
Did we notice that urxvtd.service
example above has the incorrect path for RXVT_SOCKET set in .zshenv
? Reiterates my multiple source of truth argument.
What is the best way to deal with this?
I was thinking maybe I can set the RXVT_SOCKET in urxvtd.socket
as so:
[Socket]
Environment=RXVT_SOCKET
ListenStream=%t/urxvt/urxvtd-%H
And since urxvtd.service
is a dependency then there should be a way to import environment variable. But there isn’t. So urxvtd daemon will behave as if RXVT_SOCKET is not set, but the socket will be created correctly due to urxvtd.socket
.
Then I dug a bit deeper, and systemctl --user import-environment RXVT_SOCKET
should import the variable across systemd units. Would that really be the way? Then I also need to ensure that the import happens before urxvtd.service runs. How would that work?
If I do use Xorg/i3 with systemd, I believe there should be a way to transfer the environment variable across systemd units.
At this point I am likely to believe there is no pure systemd solution to such requirement for propagation of environment variables
I ended up using a shell to wrap the ExecStart
command since the shell will inherit the environment correctly.