【问题标题】:Ansible: lineinfile module using regexp and backrefsAnsible:使用 regexp 和 backrefs 的 lineinfile 模块
【发布时间】:2019-09-30 19:06:04
【问题描述】:

我试图确保一行以 'audit=1"' 结尾。之前的状态是:

GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=vg00/lv_root rhgb 安静”

之后的状态应该是:

GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=vg00/lv_root rhgb quiet 审计=1"

使用 Ansible lineinfile 模块,如果它丢失,我可以添加该语句,但重复运行会继续附加 'audit=1"',即使它存在。我一直在使用正则表达式和负前瞻断言,只是无法获得正确的语法。

这是我的游戏示例:

  - name: grub - adjust
    lineinfile:
      path: /home/vwadmin/grub-test
      regexp: '(GRUB_CMDLINE_LINUX=.*)"(?!audit=1")'
      line: '\1 audit=1"'
      backrefs: yes
      state: present

编辑:使用和平主义者的建议,我有一个可行的解决方案。确认如果缺少我的 audit=1 语句,则添加,如果存在则不执行任何操作。

  - name: grub - check
    shell: grep -c 'audit' /etc/default/grub
    register: grub_file
    ignore_errors: true

  - name: grub - adjust
    lineinfile:
      path: /etc/default/grub
      regexp: '(GRUB_CMDLINE_LINUX=.*)"'
      line: '\1 audit=1"'
      backrefs: yes
      state: present
    when: grub_file.stdout == "0"

注意:我不禁感到,如果没有预先步骤,我无法让它工作,以及为什么它不能在 check_mode 下正常工作,是因为没有正确定义负前瞻这个案例。据我了解,当负前瞻成功时,正则表达式匹配应该失败,这应该导致模块不采取行动。在GG 上查看另一个示例,我想知道根本问题是否是第一组比赛中 .* 通配符的贪婪性质。 /耸肩

【问题讨论】:

    标签: ansible


    【解决方案1】:

    lineinfile 正在做的工作是添加line 中给出的任何内容,并且行由您的regexp 标识。因此,无论您的设置已有什么值,它都会被您的新 line 覆盖。

    您可以使用两种方法:

    1. check_modefailed_when 结合使用。
    2. 使用shell模块预先grep内容。

    Check_Mode(虽然我无法让它工作,但其他地方都推荐过):

    - name: grub - adjust
      lineinfile: 
          name: /home/vwadmin/grub-test
          regexp: '(GRUB_CMDLINE_LINUX=.*)'
          line: '\1 audit=1"'
          backrefs: yes
          state: present
       check_mode: yes
       register: presence
       failed_when: presence.changed
    

    使用 grep(这个对我来说很好用)

    - name: grub - adjust
      shell: grep -c 'audit' /home/vwadmin/grub-test 
      register: file
      ignore_errors: true
    
    - name: Present
      debug: msg="audit is present"
      when: file.stdout != "0"
    
    - name: Not Present
      debug: msg="audit is not present"
      when: file.stdout == "0"
    

    【讨论】:

      【解决方案2】:

      我想用console 内核选项做类似的事情,结果是这样的:

      - name: "Ensure console kernel options are set"
        lineinfile:
          path: /etc/default/grub
          regexp: ^GRUB_CMDLINE_LINUX=\"(?P<defaults>.*?)\s*(?P<console> console=.*)?\"$
          line: GRUB_CMDLINE_LINUX="\g<defaults> {{ kernel_console }}"
          backrefs: yes
        register: grub_changed
      
      - name: "Rebuild grub"
        command: grub2-mkconfig –o /boot/grub2/grub.cfg >/dev/null
        when:
          - grub_changed.changed
      

      正则表达式的关键部分是(?P&lt;defaults&gt;.*?):最后一个问号 - 这使得匹配不那么贪婪,允许选择可选的 console=.*,而无需在行尾不断附加另一个console line 就像你的 audit 一样。主要问题是它假定它始终是行中的最后一个(一组)选项,如果没有定义console,我总是以空格结尾。但它有效!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-09-09
        • 2015-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-14
        相关资源
        最近更新 更多