setting environment variables from command line inside unit files
Commands in ExecStart=
in systemd service units do not really run on a shell, so shell expansions (such as the command substitution $(...)
you use there) are not really available.
You can use them by calling a shell script explicitly, with /bin/sh -c '...'
, in your ExecStartPre=
. For example:
ExecStartPre=/bin/sh -c 'systemctl set-environment date=$$(/bin/date +%%Y-%%m-%%d-%%H-%%M)'
Note that you need to escape the $
itself, by using $$
, otherwise systemd will try to interpret as a systemd variable expansion. (Actually, as the next character is (
, a single $
might work there, but doubling it is the more correct setup.)
Please note that using systemctl set-environment
like you're doing is really not recommended, since you're creating a global environment variable ${date}
that will be available everywhere.
Instead, consider running your ExecStart=
command through a shell, in which case you can define a shell variable ${date}
and just use it in the single place you need it:
ExecStart=/bin/sh -c 'date=$$(/bin/date +%%Y-%%m-%%d-%%H-%%M); exec java -Xms512m -Xmx1024m ... -XX:HeapDumpPath=/u01/jetty/hdumps/hdump_$${date} -verbose:gc ...
Note again, escaping the $
with $${date}
, so systemd doesn't think it's a systemd variable to expand. Also, using exec
to ensure the shell is replaced with the java
process, making sure systemd will know what the main PID of the service is.
Escaping on systemd ExecStart=
can become complex and burdensome quite quickly... So consider instead storing the shell script in a file (in which case you don't need to worry about escaping $
and %
and about how the quotes might work slightly differently) and just run that script from the ExecStart=
, that's a lot simpler (even though it requires an extra file...)
Related videos on Youtube
zozo6015
Updated on September 18, 2022Comments
-
zozo6015 over 1 year
I am trying to set a date inside the unit file for logging
my unit file look like this:
[Unit] Description=Jetty service After=multiuser.target [Service] Environment=MAIN_CLASS="com.candorgrc.nphase.MainJetty" Type=simple User=jetty Group=jetty WorkingDirectory=/home/jetty/dist PermissionsStartOnly=true ExecStartPre=/bin/systemctl set-environment date=$(/bin/date +%%Y-%%m-%%d-%%H-%%M) ExecStart=/usr/bin/java -Xms512m -Xmx1024m -Djava.util.logging.config.file=/home/jetty/logging.properties -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/u01/jetty/hdumps/hdump_${date} -verbose:gc -Dcom.sun.management.jmxremote.port=12321 -Dcom.sun.management.jmxremote.authen PIDFile=/var/run/jetty.pid ExecReload=/bin/kill -HUP $MAINPID #Restart=on-failure ExecStop=/bin/kill -9 $MAINPID
Setting the date does not seam to be working. The error I get is the following:
Nov 26 16:47:50 vps203756 systemctl[14275]: Failed to set environment: Invalid environment assignments Nov 26 16:47:50 vps203756 systemd[1]: jetty.service: Control process exited, code=exited status=1 Nov 26 16:47:50 vps203756 systemd[1]: jetty.service: Failed with result 'exit-code'. Nov 26 16:47:50 vps203756 systemd[1]: Failed to start Jetty service.
Any idea how to configure it for it to work?
-
rogerdpack almost 5 years
-