How to use quote and dollarsign with systemd

After some research around, I found that it's ok to use quote in ExecStart definition of a systemd service file. As for using shell variable, it's necessary to use curly braces to clarify where the variable name end when non-space characters is connected to the variable itself.

In the above case, the system must have treat $DOCKER_USERNAME/redis as the variable name instead of $DOCKER_USERNAME. Add a curly braces then it is interpreted correctly.

Edit: More information about what syntax is ok with systemd can be found here: http://www.freedesktop.org/software/systemd/man/systemd.service.html#Command%20lines

Basically most shell notation is ok, with the except of pipe operators.


I've just struggled to quote and run the following command line in the ExecStart key of a service unit file:

IFS=$'\n'; f=($(ls $HOME/bk.d/DuckieTV*.backup | tail -n +2)); echo "${f[@]}"

I'll quote it using systemd quoting rules, and then I'll explain what I learned in the process. It appears complicated because we expect it to follow the quoting rules of POSIX shells, but in fact it's even simpler. Here's the ExecStart directive, properly quoted

ExecStart=/bin/bash -c 'IFS=$$\'\\n\'; f=($$(ls ${HOME}/bk.d/DuckieTV*.backup | tail -n +2)); echo \"$${f[@]}\"'

or

ExecStart=/bin/bash -c "IFS=$$\'\\n\'; f=($$(ls ${HOME}/bk.d/DuckieTV*.backup | tail -n +2)); echo \"$${f[@]}\""

So, the quoting rules:

  1. Enclose the string to be treated as a single argument either in single quotes (' ') or double quotes (" "). They are treated the same, it doesn't matter which one you choose, as long as the closing quote is the same as the opening quote
  2. Scan the string from left to right, replacing ' with \', " with \" and $ with $$

If you want systemd to do variable substitution, then don't quote $, but systemd doesn't treat $var and ${var} as the same. They are both replaced by the environment value of var, but word splitting will be different in each case: with $var, after replacing the value of var, the words will be split on whitespace, whereas with ${var} there will be no word splitting. Effectively, systemd treats $var as a POSIX shell would do, but it treats ${var} as a POSIX shell would treat "$var".

Tags:

Systemd