I wanted to update my docker.service file to include tls certificates in the start command. The idea was to search for the line that starts with ExecStart=
but also not to change anything if that line already contains tcp header -H tcp://
. It turned out to be a bit more complicated than expected.
Result
sed -i '\|^ExecStart=.*-H tcp://|! s|^ExecStart=.*|\0 -H tcp://0.0.0.0:2376 --tlsverify --tlscacert='$PWD'/ca.pem --tlscert='$PWD'/server.pem --tlskey='$PWD'/server.key|' /lib/systemd/system/docker.service
Broken in multiple lines for readability
sed -i '\|^ExecStart=.*-H tcp://|!
s|^ExecStart=.*|\0 -H tcp://0.0.0.0:2376 --tlsverify
--tlscacert='$PWD'/ca.pem --tlscert='$PWD'/server.pem
--tlskey='$PWD'/server.key|' /lib/systemd/system/docker.service
In a nutshell, it excludes all lines that start with ExecStart=
and contain -H tcp://
and out of remaining lines, if a line starts with ExecStart=
, it appends additional arguments to the end of the line.
Explanation
sed -i
means that we will change a file in place.
\|A|! s|S|R|
- using pipes instead of slashes makes it easier when dealing with paths. Note that syntax starts with a backslash when using special delimiters with addresses (A
part).
Using standard slashes would be like /A/! s/S/R/
, without leading backslash.
\|^ExecStart=.*-H tcp://|!
- using the addresses in sed, exclude lines that start with ExecStart=
and have -H tcp://
down the line.
s|^ExecStart=.*|\0 -H tcp://0.0.0.0:2376 ...
- search for a line that starts with ExecStart=
and grab the rest of the line using .*
. In the replace part, \0
will hold the complete line match and the rest is additional text that is appended to the line.
/lib/systemd/system/docker.service
- file that is being edited
Conclusion
For a single line change, a file can be checked if the update is actually required before updating it, and then the exclusion part is not needed at all. But if there are more lines that require similar update this could do the trick.
Top comments (0)