如何在 Puppet 脚本中的 sed 命令中转义“/”?

如何在 Puppet 脚本中的 sed 命令中转义“/”?

在配置文件中,我尝试用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 '\/'

答案1

如果您的 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 (`\').

答案2

在 sed 的许多版本中,你可以使用不同的字符作为分隔符,以避免必须转义 / 例如,使用 | 或 # 是很常见的

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

答案3

哇,哇……等等!Puppet 清单中的 Sed 有点疯狂。您应该使用 puppetlabs stdlib 中的 file_line 资源。

(您应该安装整个模块,但这里是自定义资源类型) 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',
  }

答案4

事实证明\\\\/作品。

例如:

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

编辑: ...但当然使用不同的分隔符,如肯尼伊恩建议,这是一个更清洁的解决方案!

相关内容