How to debug systemd unit ExecStart

I am curious whether I can print out fully expanded ExecStart/ExecStop command line. Consider following example:

ExecStart=/usr/bin/java $OPTS_COMMON $OPTS $OPTS_LOG $OPTS_DEBUG some.class.Start --param1 ${PARAM1} --param2 ${PARAM2}

I am having quite long command lines with a lot of environment variables involved. If some of the variables becomes wrong (for example by drop-in configuration), service might not start at all. However I do not see fully expanded line with substituted envs anywhere and I struggle to find out what is wrong.

I had no luck googling this and so far the only possibility I found is to modify unit file to run /usr/bin/echo instead of service itself. But that is a bit tiresome. Or even more annoying solution - check every environment variable one-by-one.

Is there some way how to force systemd to show me what is actually attempted to be run?


Unfortunately there is no built in way. To see the final ExecStart you can turn on debugging. Edit the file /etc/systemd/system.conf and set the LogLevel= to debug. Then you will see something like:

java.service About to execute: /usr/bin/java $OPTS_COMMON... This doesn't solve your problem but it is good to see the systemd's specifier replacement. https://www.freedesktop.org/software/systemd/man/systemd.unit.html(specifiers)

But if you really want to get to the bottom of argument replacement you need to look in to here: https://github.com/systemd/systemd/blob/7ce9cc154576e342015eab8c1500790a9ededc01/src/core/execute.c#L2570


Instead of using the command line to execute, use a wrapper script (or binary) with the same command and parameters. Then the wrapper script logs the parameters and then executes the real command.

Like this:

ExecStart=/path/to/wrapper /usr/bin/java $OPTS_COMMON $OPTS $OPTS_LOG $OPTS_DEBUG some.class.Start --param1 ${PARAM1} --param2 ${PARAM2}

The wrapper script itself could be:

#!/bin/sh
LOGFILE=/some/safe/file
for param
do
    echo "param: $param"
done > $LOGFILE
exec "$@"

In *.service file in section [Service]

ExecStartPre=/bin/bash -l -c 'echo "$OPTS_COMMON">/tmp/options.debug'