41

我在 /etc/foo.txt 有一个简单的文件。该文件包含以下内容:

#bar

我有以下 ansible playbook 任务来取消注释上面的行:

- name: test lineinfile
  lineinfile: backup=yes state=present dest=/etc/foo.txt
              regexp='^#bar'
              line='bar'

当我第一次运行 ansible-playbook 时,该行被取消注释并且 /etc/foo.txt 现在包含以下内容:

bar

但是,如果我再次运行 ansible-playbook,我会得到以下信息:

bar
bar

如果我再次运行它,那么 /etc/foo.txt 文件将如下所示:

bar
bar
bar

如何避免这种重复行?我只想取消注释“#bar”并完成它。

4

3 回答 3

73

如果您不想更改正则表达式,则需要添加backrefs=yes 。

- name: test lineinfile
  lineinfile: backup=yes state=present dest=/etc/foo.txt
              regexp='^#bar' backrefs=yes
              line='bar'

这将lineinfile的行为从:

 find
 if found
   replace line found
 else
   add line

至:

 find
 if found
   replace line found

换句话说,这使得操作是幂等的。

于 2014-02-21T12:24:50.593 回答
57

问题是任务的正则表达式只匹配注释掉的行,#bar. 要做到幂等,lineinfile 任务需要匹配行的注释状态未注释状态。这样它会取消注释#bar,但会bar保持不变。

这个任务应该做你想做的事:

- name: test lineinfile
  lineinfile: 
    backup=yes
    state=present
    dest=/etc/foo.txt
    regexp='^#?bar'
    line='bar'

请注意,唯一的变化是添加了“?” 到正则表达式。

于 2013-10-18T14:25:27.680 回答
3

请参阅https://github.com/ansible/ansible/issues/4531

解决方案是不替换注释掉的行,而是添加一个附加行,同时保留原来的行。

于 2013-10-15T21:05:00.143 回答