10

I am migrating from upstart to systemd. I am having a bit of trouble making the transition with the EnvironmentFile directive. I cannot get this EnvironmentFile to work:

########################################################
# Catalina Settings
CLUSTER_BASE=/d01/tomcat/prod/xyz
CATALINA_BASE=$CLUSTER_BASE/1
CATALINA_TMPDIR=$CATALINA_BASE/temp
CATALINA_HOME=/usr/share/tomcat7
CATALINA_PID=/run/tomcat/tc-prod-xyz-1.pid

########################################################
# Java Settings
JAVA_HOME=/usr/lib/jvm/default-java/jre
JAVA_OPTS=-Djava.awt.headless=true
JAVA_OPTS=$JAVA_OPTS -server
JAVA_OPTS=$JAVA_OPTS -Xms2048m
JAVA_OPTS=$JAVA_OPTS -Xmx2048m
JAVA_OPTS=$JAVA_OPTS -XX:MaxPermSize=2048m
JAVA_OPTS=$JAVA_OPTS -XX:+UseParallelGC
JAVA_OPTS=$JAVA_OPTS -XX:+AggressiveHeap
JAVA_OPTS=$JAVA_OPTS -javaagent:$CLUSTER_BASE/newrelic/newrelic.jar

It would appear that this type of statement where I re-use a variable:

JAVA_OPTS=$JAVA_OPTS -XX:+UseParallelGC

is not supported in systemd like it was in upstart. Does systemd support something like this or do I need to make one long hard to read statement?

5 Answers 5

16

Unfortunately that file you have is actually a shell script. In the past, most init systems/scripts have interpreted files which provide environment variables by using the shell, so you could get away with doing shell things in them. Systemd however does not do this. The environment file is truly an environment file, not a script. This is documented in the systemd.exec man page:

Variable expansion is not performed inside the strings, however, specifier expansion is possible. The $ character has no special meaning.

Therefore you have 2 options.

  1. Expand out all your variables manually. Meaning use CATALINA_BASE=/d01/tomcat/prod/xyz/1.

  2. Evaluate the file with the shell:
    ExecStart=/bin/bash -ac '. /path/to/env_file; exec /path/to/program'

2
  • Option #2 looks wrong. A=1, exec bash, echo $A does not print 1. C.f. export.
    – sourcejedi
    Apr 14, 2017 at 15:01
  • 4
    @sourcejedi No, it's not wrong. See the -a argument. man bash: "Automatically mark variables and functions which are modified or created for export to the environment of subsequent commands."
    – phemmer
    Apr 14, 2017 at 16:33
4

Do I need to make one long hard to read statement?

No

A line ending with a backslash will be concatenated with the following one, allowing multiline variable definitions.

1
  • So basically turn it into one very long "multiline" that works :)
    – rogerdpack
    May 30, 2019 at 16:35
2

You could use bash to expand your variables.

Environment file:

BLA=bla
BLABLA=${BLA}${BLA}

Use bash -c to execute the command:

ExecStart=/usr/bin/bash -c 'echo ${BLA} .. ${BLABLA}'

Output:

bash[4771]: bla .. blabla
2
  • This will only work in a very small number of (likely not to be used) cases. What's happening here is that systemd is actually running bash -c 'echo bla ${BLA}${BLA}'. So systemd is doing the first level of substitution, and then bash is doing the second level. If you're going to launch an application, that second level of substitution won't happen, and you'll be stuck with the variable BLABLA=${BLA}${BLA}.
    – phemmer
    Apr 14, 2017 at 12:48
  • It is possible to get second level substitution to work, FWIW, ex: unix.stackexchange.com/a/324035/8337
    – rogerdpack
    May 30, 2019 at 16:33
2

In the specific case of Tomcat (as in this question), I found that it is easier to put most of these settings in bin/setenv.sh, which is executed by Tomcat at startup, and evaluates the variables in the shell script as expected.

So in /etc/systemd/system/tomcat.service I only specify the Environment variables for CATALINA_BASE and CATALINA_HOME, and then I put the rest of the stuff in ${CATALINA_BASE}/bin/setenv.sh.

0

Another option: Have a secondary unit that runs before this one and creates an EnvironmentFile it can use: https://stackoverflow.com/a/42841480/32453

The secondary unit can use bash for instance. Seems to be the systemd way for importing env. :|

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .