【问题标题】:How do I use regex with Ansible?如何在 Ansible 中使用正则表达式?
【发布时间】:2017-04-18 02:26:27
【问题描述】:

我无法在 Ansible 2 中匹配正则表达式模式。有人可以帮我理解我做错了什么吗?谢谢。

--- # Disable auto update for Ubuntu
- hosts: nonedgeLinux
  become: yes
  tasks:
    - name: disable auto updates
      replace:
        dest: /etc/apt/apt.conf.d/50unattended-upgrades
        regexp: '(?:[ \t]*\"\${distro_id}:\${distro_codename}-security\";)'
        replace: '//  "\${distro_id}:\${distro_codename}-security\";'

我使用https://regex101.com/ 来验证正则表达式是否针对正在搜索的文件内容的复制/粘贴。此测试报告正则表达式模式是正确的。每次在 Ubuntu 16.04.2 机器上运行时,我都会得到以下结果:

root@sbx54:/data/scripts/ansible# ansible-playbook disableAutoUpdate.yml -vvvv
Using /data/scripts/ansible/ansible.cfg as config file
Loaded callback default of type stdout, v2.0
1 plays in disableAutoUpdate.yml

PLAY ****************************************************************************

TASK [setup] *******************************************************************
ESTABLISH LOCAL CONNECTION FOR USER: root
localhost EXEC ( umask 22 && mkdir -p "$( echo $HOME/.ansible/tmp/ansible-tmp-1492480514.73-9504514182168 )" && echo "$( echo $HOME/.ansible/tmp/ansible-tmp-1492480514.73-9504514182168 )" )
localhost PUT /tmp/tmpkYPc6g TO /root/.ansible/tmp/ansible-tmp-1492480514.73-9504514182168/setup
localhost EXEC LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1492480514.73-9504514182168/setup; rm -rf "/root/.ansible/tmp/ansible-tmp-1492480514.73-9504514182168/" > /dev/null 2>&1
ok: [localhost]

TASK [disable auto updates] ****************************************************
task path: /data/scripts/ansible/disableAutoUpdate.yml:15
ESTABLISH LOCAL CONNECTION FOR USER: root
localhost EXEC ( umask 22 && mkdir -p "$( echo $HOME/.ansible/tmp/ansible-tmp-1492480515.71-278594852314124 )" && echo "$( echo $HOME/.ansible/tmp/ansible-tmp-1492480515.71-278594852314124 )" )
localhost PUT /tmp/tmpG3gchf TO /root/.ansible/tmp/ansible-tmp-1492480515.71-278594852314124/replace
localhost EXEC LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1492480515.71-278594852314124/replace; rm -rf "/root/.ansible/tmp/ansible-tmp-1492480515.71-278594852314124/" > /dev/null 2>&1
ok: [localhost] => {"changed": false, "invocation": {"module_args": {"backup": false, "content": null, "delimiter": null, "dest": "/etc/apt/apt.conf.d/50unattended-upgrades", "directory_mode": null, "follow": false, "force": null, "group": null, "mode": null, "owner": null, "regexp": "(?:(?!\\/\\/).*[ \\t]*\\\"\\${distro_id}:\\${distro_codename}-security\\\";)/g", "remote_src": null, "replace": "replaced", "selevel": null, "serole": null, "setype": null, "seuser": null, "src": null, "validate": null}, "module_name": "replace"}, "msg": ""}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0

这是正在搜索的文件的片段:

Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}";
    "${distro_id}:${distro_codename}-system";
//  "${distro_id}:${distro_codename}-updates";
//  "${distro_id}:${distro_codename}-proposed";
//  "${distro_id}:${distro_codename}-backports";
};

# ansible --version
ansible 2.0.0.2
config file = /data/scripts/ansible/ansible.cfg
configured module search path = Default w/o overrides

最后一点:仅在查找字符串时,我确实在此文件中进行了搜索和替换。当寻找整条线时,这是失败的。此外,我也尝试转义特殊字符,例如[/][/] 代替 \/\/\ 等,没有运气。

【问题讨论】:

  • 你想用这个实现什么?结果似乎非常好。该字符串不在输入文件中,因此不会被替换。任务以ok 状态结束。
  • 对于这个特殊的例子,你为什么不使用lineinfile 模块?
  • @techraf:我曾尝试使用 lineinfile 模块,结果相同。因此尝试了替换模块。
  • @techraf,你能告诉我正则表达式没有找到字符串有什么问题吗?请参考片段中的第三行:"${distro_id}:${distro_codename}-system";
  • 您的输入文件中没有security 字符串。并且正则表达式引擎不会匹配securitysystem。你现在觉得开悟了吗?

标签: regex ansible ansible-2.x


【解决方案1】:

除了尝试将securitysystem 匹配的错误之外,您不需要转义任一参数中的双引号或replace 参数中的美元符号(否则反斜杠将插入到文件中):

- name: disable auto updates
  replace:
    dest: /etc/apt/apt.conf.d/50unattended-upgrades
    regexp: '(?:[ \t]*"\${distro_id}:\${distro_codename}-system";)'
    replace: '//  "${distro_id}:${distro_codename}-system";'

您可以使用lineinfile 模块获得相同的结果(这使代码更具可读性,恕我直言):

- name: disable auto updates
  lineinfile:
    dest: /etc/apt/apt.conf.d/50unattended-upgrades
    regexp: '"\${distro_id}:\${distro_codename}-system"'
    line: '//  "${distro_id}:${distro_codename}-system";'

【讨论】:

  • 感谢您帮助我了解多个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-14
相关资源
最近更新 更多