2

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

eignhpants
  • 129
  • 2
  • 7
  • Why are you calling a shell and redirecting output to a file with `>>`? Get rid of the shell and make the appropriate settings in the systemd unit itself. – Michael Hampton Oct 15 '20 at 21:07
  • I'm not sure what you mean, I'm not very experienced with systemd. I have another unit to write from a file, but this was the only way I found that works allow me to curl and output to a file. – eignhpants Oct 15 '20 at 21:51
  • https://www.freedesktop.org/software/systemd/man/systemd.exec.html#StandardOutput= – Michael Hampton Oct 15 '20 at 22:11
  • Ugh I did not read far enough in the docs clearly. This makes sense I will try this tomorrow thank you. – eignhpants Oct 16 '20 at 00:45
  • I've been using systemd for close to nine years now, so I know most of it inside and out by now. I don't expect most people will though. There's a lot there. – Michael Hampton Oct 16 '20 at 00:58
  • I suspect I may see the same problem since the `>>` isn't the broken part of this snippet however. Or would I be able to skirt some escape issue by doing `ExecStart=/bin/sh...` instead? – eignhpants Oct 16 '20 at 01:02
  • 1
    You'll be able to skirt some escaping issue by not calling the shell at all. – Michael Hampton Oct 16 '20 at 01:05
  • Apologies but, clearly I have a huge gap in knowledge. I am interpreting the above link as using that directive to output the result of `ExecStart` into the file `StandardOutput` has defined. As this function depends on curl to get the file, and sed to extract the value, where can I call those except the shell? – eignhpants Oct 16 '20 at 01:41
  • Oh wait, you're actually piping here. I missed that bit. You're probably best off writing a shell script and calling that from the systemd unit. – Michael Hampton Oct 16 '20 at 02:46

1 Answers1

1

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...
meuh
  • 1,563
  • 10
  • 11