Я пытаюсь написать сценарий bash, который будет вставлять строку после сопоставления со строкой в
/usr/lib/systemd/system/neutron-server.service
Мне удалось легко сделать это с другими файлами поскольку я просто вставлял переменные в необходимые файлы конфигурации, но этот, похоже, вызывает у меня проблемы.
Я считаю, что ошибка в том, что sed не игнорирует специальные символы. В своей попытке я попытался использовать sed одинарных и двойных кавычек (которые, как я понимаю, предназначены для переменных, но думал, что это может что-то изменить. Есть ли лучший способ сделать это или некоторые специальные флаги sed или синтаксис, которые мне не хватает?
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 - Вставить
--config-file /etc/neutron/plugins/ml2/ml2_conf_cisco_apic.ini
После
--config-file /etc/neutron/plugin.ini
Исходный файл
[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
Файл после желаемой команды изменения.
[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
Ваша проблема не в том, что sed
неправильно понял символы, а в неправильной команде a
, которую вы выбрали для развертывания в этом сценарии. Команда append, a
, помещает текст после выделенной строки, тогда как вам нужно вставить некоторый текст внутри выделенной строки. Для этого вам понадобится команда s///
.
Если это одноразовая вещь, то вы можете просто жестко закодировать замену, как уже показано DopeGhoti. Но если вам нужна операция типа «заполни и забудь», вам необходимо предпринять следующие шаги:
# 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
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
Исходный файл будет сохранен как neutron-server.service.bak
. Просто найдите строку, после которой нужно что-то вставить, и замените ее этой строкой, за которой следует вставка. Использование _
вместо /
для разделителя sed
делает сегменты замены до -и после -намного менее пикетными -.