Systemd: default value for environment variable

environment-variablesinit-scriptinit.dopenrcsystemd

I would like to migrate some OpenRC init script to systemd but I think that it is general problem of environment variables handling in systemd.

Original OpenRC files

There is a file e.g. /etc/conf.d/fooservice with contents

# value of FOO variable
# you can override default value by uncomenting this line
# FOO=value1

# value of BAR variable
BAR=value2

In original startup script /etc/init.d/fooservice, there was

FOO=${FOO:-default_foo_value}
BAR=${BAR:-default_bar_value}

So the result was $FOO==default_foo_value and $BAR==value2

Migrated systemd files

Now I have systemd service file /usr/lib/systemd/system/fooservice.service, that contains

[Service]
EnvironmentFile=/etc/conf.d/fooservice
ExecStart=/usr/bin/fooservice $FOO $BAR

But there is a problem that $FOO is not initialized to default_foo_value

Is there a way to tell systemd to use default value if there is no value in environment file? Is there a way to use intermediate environment file with default values or multiple chained Environment files?

SOLUTION:

This is not good way. /etc/conf.d/fooservice file can be incompatible because it is "shell script" and systemd expects "environment file". In basic value assignment, it seems similar, but it is not the same thing.

Prefered solution for this by Gentoo is to put everything into service file and configuration file of the service and not to use additional conf.d file.

WORKING BUT NOT PREFERED SOLUTION:

Use this only as fast hack to run OpenRC service as systemd one.

/usr/lib/systemd/system/fooservice.service now contains

[Service]
Environment="FOO=default_foo_value"
Environment="BAR=default_bar_value"
EnvironmentFile=/etc/conf.d/fooservice
ExecStart=/usr/bin/fooservice $FOO $BAR

Best Answer

systemd is not a shell, so it does not support shell-specific substitutions in environment files. Their format is simply KEY=VALUE, with possible empty lines and comments in between.

To quote systemd.exec(5):

Settings from these files override settings made with Environment=. If the same variable is set twice from these files, the files will be read in the order they are specified and the later setting will override the earlier setting.

So, you can accomplish your task by either:

  • using multiple EnvironmentFile= directives (they override each other in the order of specification)

  • using Environment= in the service file to specify default values (any EnvironmentFile= will override it)