我正在使用厨师食谱来更新节点上的配置文件。该文件的内容如下所示:
server server1.domain.com
server server2.domain.com
我的属性文件中定义了一个ruby数组,如下所示:
default['servers'] = %w(xyz.domain.com abc.domain.com)
我想以递归方式使用sed替换文件中的服务器值,以便我的文件更新如下:
server xyz.domain.com
server abc.domain.com
我在我的食谱中尝试了以下ruby循环:
(node['servers']).each_with_index do |ntserver,index|
bash "server set" do
code <<-EOH
sed -i 's|server .*|server #{node['servers'].at(index)}|' /etc/ntp.conf
EOH
end
end
但是在运行chef-client并分别应用更改之后,配置文件的内容如下:
server abc.domain.com
server abc.domain.com
我是sed命令的新手,所以无法弄清楚我哪里出错了。 任何帮助将不胜感激。
答案 0 :(得分:3)
按照设计,您不应该使用Chef修改文件。相反,您使用cookbook_file资源覆盖整个文件,或者,如果您需要使用template资源将一些动态值插入到文件中。
答案 1 :(得分:1)
sed
命令(你使用它的方式)非常简单;它仅执行(由于-i
选项而在给定文件中就位)用字符串server .*
替换匹配模式server #{node['servers'].at(index)}
的每个字符串。它在整个文件中执行此操作,因此每个循环都会更改整个文件中的所有实例。
让我感到困扰的是你在原版中写了server1.domain.com
,但是你得到的格式是server .*
(意思是server
,后跟一个空格{ {1}}以及任意数量的其他字符)。由于空间,这不应该匹配任何东西,所以根本不需要改变任何东西。但也许你只是在发布问题时错误地把那个空间放在那里。我假设你的实际代码中没有这样的空间,因为这样就可以适应观察到的现象。
因此,要一次只更改一行,您应该在循环中有一个计数器并且在搜索模式中具有迭代次数,因此第一次迭代时.*
为server1.*
,{{ 1}}为第二个,依此类推。然后每次迭代只会改变一行,你应该得到你想要的结果。