我在/etc/foo.txt 有一个简单的文件。该文件包含以下内容:
#bar
我有以下 ansible 剧本任务来取消注释上面的行:
- 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"并完成它。
如果您不想更改正则表达式,则需要添加 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
换句话说,这使得操作是幂等的。
问题是任务的正则表达式仅与注释掉的行匹配,#bar
.要实现幂等,lineinfile 任务需要同时匹配行的注释和未注释状态。这样,它将取消注释#bar
但bar
保持不变。
此任务应执行所需的操作:
- name: test lineinfile
lineinfile:
backup: yes
state: present
dest: /etc/foo.txt
regexp: '^#?bar'
line: 'bar'
请注意,唯一的更改是向正则表达式添加?
。
请参阅 https://github.com/ansible/ansible/issues/4531。
解决方案是不替换注释掉的行,而是添加一行额外的行,同时保留原始行。
对于那些在查看了充满重复行的文件后来到这里的人:删除重复项并恢复到"良好状态"的一种简单方法是,在原始正则表达式中使用"state=absent"。
例如:
- name: clean KexAlgorithms
lineinfile: dest=/etc/ssh/sshd_config
regexp="^KexAlgorithms"
state=absent
然后正确重新添加它们。