Systemd ExecStart – Troubleshooting Escape Characters Failures

cloud-initJenkinssedsystemd

I have the following snippet to extract a value from a jenkins server jnlp config file. It works out of the box in the terminal but not as a unit. I want a unit so I can put the value somewhere and use it as an environment variable. However I keep getting an escape sequence error. I found this which suggests I only need to worry about quotes and slashes, but I get the same result. Here is the ExecStart of the file with the sed included:

ExecStart=/bin/sh -c 'curl -L -s -X GET http://10.x.x.x:8080/computer/name-of-executor/slave-agent.jnlp | sed \"s/.*<application-desc main-class=\"hudson.remoting.jnlp.Main\"><argument>\([a-z0-9]*\).*/\1/\" >> /etc/build_environment'

I have tried many combinations of escape characters to no avail. Additionally, I use an identical pattern to extract a value from metadata (using curl, piping, etc) and that works fine. Definitely confused on what is happening here

Best Answer

The easy way to debug this is to add option -v to the sh -c in order to see what systemd is actually passing it. If we do this we can see we are getting (reduced for readability):

curl ... | sed "s/... main-class="hudson...">.../\1/" >>...

The syntax error is that the double-quoted command given to sed has inside it " instead of \". This is because systemd replaces \" by " indiscriminately in the ExecStart string.

You need to pass a backslash to sh by using \\ (which systemd will reduce to \), then the double-quote:

ExecStart=/bin/sh -cv 'curl... | sed "s/...main-class=\\"hudson...