Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

In a config file, I'm trying to replace PREFIX=/jenkins with, say, PREFIX=/foobar.

On the (bash) command line, this works fine:

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

However, in a Puppet script (.pp file):

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

produces:

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] 

How to escape the sed command properly? Or is something else the matter?

I also tried with \\\/, but that yields: warning: Unrecognised escape sequence '\/'

share|improve this question
2  
It may be a better idea to let Puppet manage the whole /etc/default/jenkins file using a template, than to rely on an exec calling sed. –  daff Mar 11 '13 at 12:35
    
@daff: Yes, probably... But for my simple needs, for now, this suffices (and I'm not really familiar with Puppet templates yet). Later on I might change it to a more idiomatic Puppet approach. –  Jonik Mar 12 '13 at 8:01

4 Answers 4

up vote 4 down vote accepted

In cases where your sed expression contains a '/', you may want to consider using a different delimiter. I chose the pipe symbol in this example.

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

Using this syntax in your Puppet manifest would be a lot cleaner and more readable, in my opinion.


From the sed info page:

\%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 (`\').
share|improve this answer
    
This was new to me, but yes, it's a lot cleaner this way. Thanks (to both answerers)! –  Jonik Mar 11 '13 at 12:39

On many versions of sed you can use a different character as a delimiter to avoid having to escape / e.g it's quite common to use | or #

sed -i.bak 's#PREFIX=/jenkins#PREFIX=/foobar#g' /etc/default/jenkins
share|improve this answer

Whoa, whoa... hang-on! Sed in a puppet manifest is a bit crazy. You should be using the file_line resource, from the puppetlabs stdlib.

(you should install the entire module, but here is the custom resource type) https://github.com/puppetlabs/puppetlabs-stdlib/blob/master/lib/puppet/type/file_line.rb

Example:

  file_line { 'sudo_rule':
    path => '/etc/sudoers',
    line => '%sudo ALL=(ALL) ALL',
  }
share|improve this answer
    
Thanks! file_line together with match attribute is exactly what did the job! –  Laas Jun 11 at 15:43

Turns out \\\\/ works.

For example:

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

Edit: ...but of course using a different delimiter, as Kenny and Iain suggested, is a lot cleaner solution!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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