I am trying to use systemd's EnvironmentFile and add an option to the command when it is set in the file. I have the following in the unit file:

ExecStart=/usr/bin/bash -c "echo ${PORT:+port is $PORT}"

which doesn't echo anything when I start the service.

The following works as expected:

ExecStart=/usr/bin/bash -c "echo port is $PORT"

which means that the file is read correctly.

Parameter substitution also works on command line:

$ PORT=1234 bash -c 'echo ${PORT:+port is $PORT}'
port is 1234

What am I missing?


systemd does its own minimalistic shell-style command line parsing of the contents of ExecStart= and other parameters. This minimalistic parsing supports basic environment variable substitution but apparently not things like ${PORT:+port is $PORT}.

You will want to prevent systemd from doing that and let the invoked shell handle it.

From the documentation:

To pass a literal dollar sign, use "$$".

So try this:

ExecStart=/usr/bin/bash -c "echo $${PORT:+port is $$PORT}"

Or better yet, try this:

ExecStart=/bin/sh -c "echo $${PORT:+port is $$PORT}"

because the type of variable expansion you are doing here is POSIX standard and is not a bash-ism. By using /bin/sh instead of bash you will remove an unnecessary dependancy on bash.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.