问题描述
在使用 Ansible 2.7.9 时,遇到了在 lineinfile 模块中使用正则表达式的问题。他想要删除一个文件中的某一行,但是由于 {{ inventory_hostname }} 中包含了点号,他尝试使用 replace 函数来转义这些点号。他的 playbook 中的任务如下所示:
- name: Remove LE webroot definition
lineinfile:
path: "/etc/path/to/config/{{ inventory_hostname }}.conf"
regexp: "^{{ inventory_hostname | replace('.', '\.') }} = /path/to/a/directory"
state: absent
然而,在执行 playbook 时,出现了以下错误:
[...]The offending line appears to be:
path: "etc/path/to/config/{{ inventory_hostname }}.conf"
regexp: "^{{ inventory_hostname | replace('.', '\.') }} = /path/to/a/directory"
^ here
We could be wrong, but this one looks like it might be an issue with missing quotes. Always quote template expression brackets when they start a value. For instance:[...]
用户已经使用了双引号,而且所有的示例也都是使用这种语法。他想知道自己在哪里出错了。感谢任何帮助。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
解决方案1
根据最佳回答,如果在正则表达式中也转义反斜杠,问题就会得到解决:
- name: Remove LE webroot definition
lineinfile:
path: "/etc/path/to/config/{{ inventory_hostname }}.conf"
regexp: "^{{ inventory_hostname | replace('.', '\\.') }} = /path/to/a/directory"
state: absent
在上面的示例中,我们在正则表达式中也转义了反斜杠。这样就可以正确地匹配文件中的行了。
解决方案2
如果你不想在正则表达式中转义反斜杠,你可以使用 quote
过滤器来引用整个正则表达式:
- name: Remove LE webroot definition
lineinfile:
path: "/etc/path/to/config/{{ inventory_hostname }}.conf"
regexp: "{{ inventory_hostname | replace('.', '.') | quote }} = /path/to/a/directory"
state: absent
在上面的示例中,我们使用 quote
过滤器将整个正则表达式引用起来,这样就不需要手动转义反斜杠了。
解决方案3
如果你不想使用 lineinfile
模块,你还可以使用 replace
模块来实现相同的效果:
- name: Remove LE webroot definition
replace:
path: "/etc/path/to/config/{{ inventory_hostname }}.conf"
regexp: "^{{ inventory_hostname | replace('.', '\\.') }} = /path/to/a/directory"
replace: ""
在上面的示例中,我们使用 replace
模块来替换文件中的匹配行为空字符串,从而达到删除行的效果。
以上是几种解决方案,你可以根据自己的需求选择其中一种来解决问题。希望对你有帮助!
正文完