Como escapar “/” em um comando sed no script Puppet?

3

Em um arquivo de configuração, estou tentando substituir PREFIX=/jenkins por PREFIX=/foobar .

Na linha de comando (bash), isso funciona bem:

sed -i.bak s/PREFIX=\/jenkins/PREFIX=\/foobar/g /etc/default/jenkins

No entanto, em um script Puppet (arquivo .pp):

exec { 'Change-prefix':
  command => "sed -i.bak s/PREFIX=\/jenkins/PREFIX=\/foobar/g /etc/default/jenkins",
  path    => ["/bin"],
}

produz:

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] 

Como escapar do comando sed corretamente? Ou é outra coisa?

Eu também tentei com \\/ , mas isso rende: warning: Unrecognised escape sequence '\/'

    
por Jonik 11.03.2013 / 13:05

4 respostas

4

Nos casos em que sua expressão sed contém um '/', convém considerar o uso de um delimitador diferente. Eu escolhi o símbolo pipe neste exemplo.

sed -i.bak 's|PREFIX=/jenkins|PREFIX=/foobar|g' /etc/default/jenkins

Usar essa sintaxe no manifesto do Puppet seria muito mais claro e legível, na minha opinião.

Na página de informações do sed:

\%REGEXP%' (The%' may be replaced by any other single character.)

 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 ('\').
    
por 11.03.2013 / 13:15
4

Em muitas versões do sed você pode usar um caractere diferente como um delimitador para evitar ter que escapar / por exemplo, é bastante comum usar | ou #

sed -i.bak 's#PREFIX=/jenkins#PREFIX=/foobar#g' /etc/default/jenkins
    
por 11.03.2013 / 13:16
3

Whoa, whoa ... espere! Sed em um manifesto de marionetes é um pouco louco. Você deve estar usando o recurso file_line, do stdlib do puppetlabs.

(você deve instalar o módulo inteiro, mas aqui está o tipo de recurso personalizado) link

Exemplo:

  file_line { 'sudo_rule':
    path => '/etc/sudoers',
    line => '%sudo ALL=(ALL) ALL',
  }
    
por 12.03.2013 / 07:38
1

Acontece que \\/ funciona.

Por exemplo:

exec { 'Change-prefix':
  command => "sed -i.bak s/PREFIX=\\/jenkins/PREFIX=\\/foorbar/g /etc/default/jenkins",
  path    => ["/bin"],           
}

Editar : ... mas claro, usando um delimitador diferente, como Kenny e Iain sugeriu, é uma solução muito mais limpa!

    
por 11.03.2013 / 13:08