systemd unit files and "environment variables"
I recently got stuck with a simple systemd detail about environment variables processing. They are actually handled differently from any regular bash variable we are used to deal with.
I was trying to write the Tomcat 7 service unit for Arch Linux. Everything worked fine except for the CATALINA_OPTS
variable not beeing correctly interpreted when made of multiple parameters. The usual JVM heap options -Xms512m -Xmx1024m
for instance were not correctly handled: only the first parameter was passed on to Tomcat.
This was one of my first attempt: Unit file:
...
[Service]
...
EnvironmentFile=/etc/conf.d/tomcat7
ExecStart=/usr/share/tomcat7/bin/startup.sh ${CATALINA_OPTS}
ExecStop=/usr/share/tomcat7/bin/shutdown.sh
...
/etc/conf.d/tomcat7
conf file:
...
CATALINA_OPTS=-Xms512m -Xmx1024m
...
This does not work because environment variables in systemd are handled differently if used with ${MYVAR}
or with $MYVAR
.
${MYVAR}
will provide the target process with a single string argument made of the complete string you specified inMYVAR
.$MYVAR
in the other hand will splitMYVAR
around spaces it contains and feed them to the process.
I have tried many things like surrounding the CATALINA_OPTS
with simple quotes, double-quotes until this blog post.
So the correct unit file
...
[Service]
...
EnvironmentFile=/etc/conf.d/tomcat7
ExecStart=/usr/share/tomcat7/bin/startup.sh $CATALINA_OPTS
ExecStop=/usr/share/tomcat7/bin/shutdown.sh
...
Have a look at the final unit file and the corresponding configuration file for a complete example.