Guillaume ALAUX bio photo

Guillaume ALAUX

An IT passionate

LinkedIn Github

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 in MYVAR.
  • $MYVAR in the other hand will split MYVAR 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.