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