0

I am attempting to write a bash script that will insert a string after matching on a string in

/usr/lib/systemd/system/neutron-server.service

I have been able to do this on other files easily as I was just insert variables into neccessary config files, but this one seems to be giving me trouble.

I believe the error is that sed is not ignoring the special characters. In my attempt I have tried using sed of single quotes and double quotes (which I understand are for variables, but thought it might change something. Is there a better way of going about this or some special sed flags or syntax I am missing?

sed ‘/--config-file /etc/neutron/plugin.ini/a\--config-file /etc/neutron/plugins/ml2/ml2_conf_cisco_apic.ini‘ /usr/lib/systemd/system/neutron-server

TL;DR - Insert

--config-file /etc/neutron/plugins/ml2/ml2_conf_cisco_apic.ini 

After

--config-file /etc/neutron/plugin.ini

Orginial File

[Unit]
Description=OpenStack Neutron Server
After=syslog.target network.target

[Service]
Type=notify
User=neutron
ExecStart=/usr/bin/neutron-server --config-file /usr/share/neutron/neutron-
dist.conf --config-dir /usr/share/neutron/server --config-file 
/etc/neutron/neutron.conf --config-file /etc/neutron/plugin.ini --config-dir 
/etc/neutron/conf.d/common --config-dir /etc/neutron/conf.d/neutron-server -
-log-file /var/log/neutron/server.log
PrivateTmp=true
NotifyAccess=all
KillMode=process
TimeoutStartSec="infinity"

[Install]
WantedBy=multi-user.target

File after desired change command.

[Unit]
Description=OpenStack Neutron Server
After=syslog.target network.target

[Service]
Type=notify
User=neutron
ExecStart=/usr/bin/neutron-server --config-file /usr/share/neutron/neutron-
dist.conf --config-dir /usr/share/neutron/server --config-file 
/etc/neutron/neutron.conf --config-file /etc/neutron/plugin.ini --config-
file /etc/neutron/plugins/ml2/ml2_conf_cisco_apic.ini --config-dir 
/etc/neutron/conf.d/common --config-dir /etc/neutron/conf.d/neutron-server -
-log-file /var/log/neutron/server.log
PrivateTmp=true
NotifyAccess=all
KillMode=process
TimeoutStartSec="infinity"

[Install]
WantedBy=multi-user.target
0
sed -i.bak 's_--config-file /etc/neutron/plugin.ini_& --config-file /etc/neutron/plugins/ml2/ml2_conf_cisco_apic.ini_' /usr/lib/systemd/system/neutron-server.service  

The original file will be preserved as neutron-server.service.bak. Simply search for the string to insert something after, and replace it with that string followed by the insertion. Using _ rather than / for the sed delimiter makes the before- and after-replacement segments a lot less picket-fencey.

0

Your problem is not of any characters misunderstood by sed, rather it is the incorrect command a you've chosen to deploy in this scenario. The append, a, command puts text after the selected line, whereas, what you need is the insertion of some text inside of the selected line. For this, you need the s/// command.

If it's a one-time thing, then you can just hardcode the substitution as already shown by DopeGhoti. But if you want a fill-it-and-forget-it type of an operation, then you need to take these steps:


  1. Define your search & replace strings.
  2. Prepare an escaped version of these strings so that no matter what they contain, you don't need to fiddle with your sed command again.
  3. Run the command using the escaped strings rather than originals.

 # define strings
srch='--config-file /etc/neutron/plugin.ini'
repl='--config-file /etc/neutron/plugins/ml2/ml2_conf_cisco_apic.ini'

# generate their escaped versions
srch_esc=$(printf '%s\n' "$srch"  | sed -e 's|[][^\/.*$]|\\&|g')
repl_esc=$(printf '%s\n' "$repl"  | sed -e 's|[\&/]|\\&|g;$!s/$/\\/')

# run
sed -e '
   /^\[Service]/,/^$/!b
   /^ExecStart=/!b
   '"s/[[:space:]]${srch_esc}[[:space:]]/&${repl_esc} /"'
' yourfile

Explanation

  1. Select the appropriate range where you want the substitution to happen, in your case it is within lines spanning from [Service] ... empty line. By so doing, we reduce the chances of making a change in an unwanted area.
  2. Once within range, we zero in on the line of interest, in your case it is on line beginning with ExecStart=.
  3. Here we just use the escaped variables instead of the originals and also we get out of single quotes, get in double quotes ... place data ... get out double quotes, get back in single quotes. (to keep the quoting universe happy)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.