Referencing Other Environment Variables in Systemd

Jason Waldrip picture Jason Waldrip · Jun 16, 2016 · Viewed 11.2k times · Source

Is is possible to reference other environment variables when setting new ones in systemd?

[Service]
EnvironmentFile=/etc/environment
Environment=HOSTNAME=$COREOS_PRIVATE_IPV4
Environment=IP=$COREOS_PRIVATE_IPV4
Environment=FELIX_FELIXHOSTNAME=$COREOS_PRIVATE_IPV4

The above code does not seem to be working.

Answer

grochmal picture grochmal · Jun 16, 2016

This is really a question for unix & linux. But nevertheless: No, systemd will not perform environment variable expansion inside Environment=. From man systemd.exec:

   Environment=
       Sets environment variables for executed processes. Takes a space-separated list of variable assignments. This
       option may be specified more than once, in which case all listed variables will be set. If the same variable is
       set twice, the later setting will override the earlier setting. If the empty string is assigned to this option,
       the list of environment variables is reset, all prior assignments have no effect. Variable expansion is not
       performed inside the strings, however, specifier expansion is possible. The $ character has no special meaning.
       If you need to assign a value containing spaces to a variable, use double quotes (") for the assignment.

       Example:

           Environment="VAR1=word1 word2" VAR2=word3 "VAR3=$word 5 6"

       gives three variables "VAR1", "VAR2", "VAR3" with the values "word1 word2", "word3", "$word 5 6".

As you see from the example in the documentation $word just means $word no expansion will be performed. The specifiers that that man talks about are the %i, %n, %u, etc. They're in man systemd.unit (under their own man section).


On the other hand ExecStart= and its derivatives will perform environment variable expansion. Using environment variables on the ExecStart= is the common workaround for extra environment variables in systemd. I believe, that is also one of the reasons why so many recent programs accept the same parameters from the environment and from command line parameters.

An example of expansion in ExecStart=, from man systemd.service:

   Example:

       Environment="ONE=one" 'TWO=two two'
       ExecStart=/bin/echo $ONE $TWO ${TWO}

   This will execute /bin/echo with four arguments: "one", "two", "two", and "two two".

   Example:

       Environment=ONE='one' "TWO='two two' too" THREE=
       ExecStart=/bin/echo ${ONE} ${TWO} ${THREE}
       ExecStart=/bin/echo $ONE $TWO $THREE

   This results in echo being called twice, the first time with arguments "'one'", "'two two' too", "", and the second
   time with arguments "one", "two two", "too".

systemd has its documentation spread out across several man's, but one gets used to them after a while.