Как избежать "/" в команде sed в сценарии Puppet?
В конфигурационном файле я пытаюсь заменить PREFIX=/jenkins
с, скажем, PREFIX=/foobar
,
В командной строке (bash) это работает нормально:
sed -i.bak s/PREFIX=\\/jenkins/PREFIX=\\/foobar/g /etc/default/jenkins
Однако в сценарии Puppet (файл.pp):
exec { 'Change-prefix':
command => "sed -i.bak s/PREFIX=\\/jenkins/PREFIX=\\/foobar/g /etc/default/jenkins",
path => ["/bin"],
}
производит:
err: /Stage[main]//Exec[Change-prefix]/returns: change from notrun to 0 failed:
sed -i.bak s/PREFIX=\/jenkins/PREFIX=\/foobar/g /etc/default/jenkins
returned 1 instead of one of [0]
Как правильно избежать команды sed? Или дело в другом?
Я тоже пробовал с \\\/
, но это дает: warning: Unrecognised escape sequence '\/'
4 ответа
В тех случаях, когда ваше выражение sed содержит символ '/', вы можете рассмотреть возможность использования другого разделителя. Я выбрал символ трубы в этом примере.
sed -i.bak 's|PREFIX=/jenkins|PREFIX=/foobar|g' /etc/default/jenkins
На мой взгляд, использование этого синтаксиса в манифесте Puppet будет намного чище и более читабельным.
Со страницы информации о sed:
\%REGEXP%' (The
% 'может быть заменен любым другим отдельным символом.)This also matches the regular expression REGEXP, but allows one to use a different delimiter than `/'. This is particularly useful if the REGEXP itself contains a lot of slashes, since it avoids the tedious escaping of every `/'. If REGEXP itself includes any delimiter characters, each must be escaped by a backslash (`\').
Во многих версиях sed вы можете использовать другой символ в качестве разделителя, чтобы избежать необходимости экранировать / например, это довольно часто используется | или же #
sed -i.bak 's#PREFIX=/jenkins#PREFIX=/foobar#g' /etc/default/jenkins
Воу, воу... подожди! Сед в манифесте марионетки немного сумасшедший. Вы должны использовать ресурс file_line из stdlib puppetlabs.
(вы должны установить весь модуль, но вот пользовательский тип ресурса) https://github.com/puppetlabs/puppetlabs-stdlib/blob/master/lib/puppet/type/file_line.rb
Пример:
file_line { 'sudo_rule':
path => '/etc/sudoers',
line => '%sudo ALL=(ALL) ALL',
}
Оказывается \\\\/
работает.
Например:
exec { 'Change-prefix':
command => "sed -i.bak s/PREFIX=\\\\/jenkins/PREFIX=\\\\/foorbar/g /etc/default/jenkins",
path => ["/bin"],
}
Изменить: ... но, конечно, использование другого разделителя, как предложили Кенни и Иэн, является более чистым решением!