不可能在一个步骤中使用反向引用修改一行,或者如果缺少该行则添加该行。要修改现有的挂载点,需要反向引用。例如,给定测试文件
shell> cat etc/export1
/srv/files 172.16.0.14(rw,no_root_squash,no_subtree_check)
shell> cat etc/export2
/srv/files 172.16.0.15(rw,no_root_squash,no_subtree_check)
shell> cat etc/export3
/srv/download 172.16.0.14(rw,no_root_squash,no_subtree_check)
任务
tasks:
- lineinfile:
path: "etc/{{ item }}"
regex: '^{{ mount }}(\s+)({{ ipr }})*({{ optionsr }})*(\s*)(.*)$'
line: '{{ mount }}\g<1>{{ ip }}{{ options }} \g<5>'
backrefs: true
vars:
mount: /srv/files
ipr: '172\.16\.0\.14'
ip: '172.16.0.14'
optionsr: '\(.*?\)'
options: '(root_squash,no_subtree_check)'
loop:
- export1
- export2
- export3
给
--- before: etc/export1 (content)
+++ after: etc/export1 (content)
@@ -1 +1 @@
-/srv/files 172.16.0.14(rw,no_root_squash,no_subtree_check)
+/srv/files 172.16.0.14(root_squash,no_subtree_check)
changed: [localhost] => (item=export1)
--- before: etc/export2 (content)
+++ after: etc/export2 (content)
@@ -1 +1 @@
-/srv/files 172.16.0.15(rw,no_root_squash,no_subtree_check)
+/srv/files 172.16.0.14(root_squash,no_subtree_check) 172.16.0.15(rw,no_root_squash,no_subtree_check)
changed: [localhost] => (item=export2)
ok: [localhost] => (item=export3)
前两个文件没问题。问题是第三个文件。该行尚未添加到文件中。从backrefs引用
“...如果正则表达式在文件中的任何地方都不匹配,则文件将保持不变。”
解释很简单。如果正则表达式不匹配,则没有组。如果没有组,则无法创建该行。
另一方面,引用正则表达式
“ ...如果正则表达式不匹配,则该行将添加到文件中... ”
因此,如果正则表达式不匹配,则无法要求lineinfile添加一行,同时,如果正则表达式匹配,则不执行任何操作。如果正则表达式匹配,则需要反向引用。如果您使用反向引用,则不能添加缺失的行。
为了解决这个问题,读取文件的内容并创建一个字典
- command: "cat etc/{{ item }}"
register: result
loop: [export1, export2, export3]
- set_fact:
content: "{{ dict(_files|zip(_lines)) }}"
vars:
_lines: "{{ result.results|map(attribute='stdout_lines')|list }}"
_files: "{{ result.results|map(attribute='item')|list }}"
给
content:
export1:
- /srv/files 172.16.0.14(rw,no_root_squash,no_subtree_check)
export2:
- /srv/files 172.16.0.15(rw,no_root_squash,no_subtree_check)
export3:
- /srv/download 172.16.0.14(rw,no_root_squash,no_subtree_check)
现在仅在缺少时添加该行,即如果安装点已经存在则不要替换该行
- lineinfile:
path: "etc/{{ item }}"
line: '{{ mount }} {{ ip }}{{ options }}'
vars:
mount: /srv/files
ip: '172.16.0.14'
options: '(root_squash,no_subtree_check)'
loop: "{{ content|list }}"
when: content[item]|select('search', mount)|length == 0
给
skipping: [localhost] => (item=export1)
skipping: [localhost] => (item=export2)
--- before: etc/export3 (content)
+++ after: etc/export3 (content)
@@ -1 +1,2 @@
/srv/download 172.16.0.14(rw,no_root_squash,no_subtree_check)
+/srv/files 172.16.0.14(root_squash,no_subtree_check)