In a previous posting, Environment variables set by systemd, variables were directly set within the systemd unit file. This is fine for a small amount of modifications, but in some case these environment variables are provided by another package on the system or need to be the same for multiple services.

We have modified our Python application to print all environment variables that are set to make this example easier.

#!/usr/bin/env python3

import os

for param in os.environ.keys():
    print("%20s %s" % (param, os.environ[param]))

We create the first environment file /usr/local/env/file1 with the content as below to assign string values to variables. Just as in the systemd unit file no string interpolation is being done, only lines with an equal sign are processed and everything after a hash sign is ignored.

FVAR1="test1"
FVAR2="test2"

We also create a second environment file /usr/local/env/file2 with the content below. Directly we see that variable FVAR1 is also be declared in this environment file.

FVAR1="TEST1"
FVAR3="Test3"

To use the environment files we need to declare them in the systemd unit file below. The line for file1 shows that we require the file to be present otherwise the service will fail, but for file2 the filename has been preceded by a hyphen to indicate to systemd that the file is optional and no error will be generated if it is absent.

[Unit]
Description=App Service

[Service]
Type=simple
EnvironmentFile=/usr/local/env/file1
EnvironmentFile=-/usr/local/env/file2
Environment="VAR0=hello world"
ExecStart=/usr/local/bin/app

After restarting the application with systemd all the environment variables that were set are shown in the system journal. The most interesting variable shown is FVAR1 as we declared it in two files earlier and we see that the value set in file1 was replaced by the value set in file2 that was processed later.

$ sudo systemctl daemon-reload
$ sudo systemctl restart app.service
$ sudo journalctl -u app
Aug 12 09:43:35 server.example.org systemd[1]: Started App Service.
Aug 12 09:43:35 server.example.org app[4483]: LANG en_US.UTF-8
Aug 12 09:43:35 server.example.org app[4483]: VAR0 hello world
Aug 12 09:43:35 server.example.org app[4483]: FVAR2 test2
Aug 12 09:43:35 server.example.org app[4483]: FVAR3 Test3
Aug 12 09:43:35 server.example.org app[4483]: FVAR1 TEST1
Aug 12 09:43:35 server.example.org app[4483]: PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

While the purpose isn’t directly clear for everyone in the beginning, the most common use-case for enterprises is to manage environment variables that need to be set for Oracle for example. As lot of developers and engineers struggle why ORACLE_HOME isn’t being set while /etc/profile.d/oraenv.sh is present and works fine on other platforms like IBM AIX.

Published by Hans Spaans

Unix & security consultant with a passion for Linux, Solaris, PostgreSQL, Perl and network services, but also a strong believer in open and free source, standards and content.