Ansible 替换还是 lineinfile?

问题描述 投票:0回答:1

全部,

我一整天都在试图解决一些问题,我无法使用 shell 模块和 sed,但无法使用更原生的方式(例如替换或 lineinfile)来完成它。这就是我正在尝试做的:

我有一个文件,其中有几行,有些行以不同的字符串开头,但其他行以相同的字符串开头,这是我想要编辑的字符串,然后所有行在某个点都有一个特定的字符串,我想编辑这个字符串仅在以该特定字符串开头的行上。

这是一个更直观的例子:

顺便说一句,该文件是 /etc/fstab,看起来像这样

Aaaaa:/mount1  /mountpoint1 nfs mount-options 0 0
Aaaaa:/mount2  /mountpoint4 nfs mount-options 0 0
Bbbbbn:/mount1  /mountpoin9  nfs mount-options 0 0

正如您在本示例中看到的,我想要更改的安装选项是相同的,但是我只想编辑以 aaaa 开头的行中的选项。

有任何线索如何使用像replace或lineinfile这样的模块而不是使用shell的sed来做到这一点吗?

谢谢

更新: 让我澄清一下,aaaaa: 直到 nfs mount-options 0 0 之后的内容可以是任何内容,因为服务器上的挂载文件夹和挂载点可以是任何内容。 这也是我使用 shell 模块让它工作的方法,仍然在寻找更原生的模块而不是 shell:

  - name: Inserting new mounting options
    shell: sed -i '/^aaaaa/ s/mount-options/new-mount-options/g' /etc/fstab

在上面的示例中,我成功定位以 aaaaa 开头的行,并将挂载选项替换为不同的行,同时保留末尾的 0 0。

regex sed ansible
1个回答
1
投票

模块替换更适合用例。请参阅下面的示例。例如,让我们

  • dump fsck
    设置为
    1 1
    ,其中行以
    Aaaaa
  • 开头
  • fstype
    设置为
    ext4
    ,其中行以
    Bbbbbn
  • 开头

下面的任务

- replace:
    path: /scratch/fstab
    regexp: "{{ item.regexp }}"
    replace: "{{ item.replace }}"
  loop:
    - regexp: '^Aaaaa(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)(.*)$'
      replace: 'Aaaaa\1 \2 \3 \4 1 1'
    - regexp: '^Bbbbbn(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)(.*)$'
      replace: 'Bbbbbn\1 \2 ext4 \4 \5 \6'

给予

shell> cat fstab
Aaaaa:/mount1 /mountpoint1 nfs mount-options 1 1
Aaaaa:/mount2 /mountpoint4 nfs mount-options 1 1
Bbbbbn:/mount1 /mountpoin9 ext4 mount-options 0 0

注意:正则表达式很麻烦。我无法开始工作在 Python 正则表达式中捕获重复子模式


更新

如果您可以安装jc,请以系统方式更新fstab。例如,给定用于测试的文件

shell> cat /tmp/fstab 
Aaaaa:/mount1  /mountpoint1 nfs mount-options 0 0
Aaaaa:/mount2  /mountpoint4 nfs mount-options 0 0
Bbbbbn:/mount1  /mountpoin9  nfs mount-options 0 0

声明路径

  fstab_path: /tmp/fstab

并将文件获取到控制器

    - fetch:
        src: "{{ fstab_path }}"
        dest: /tmp/ansible/fstab/

声明控制器上的本地路径

  fstab_local: "/tmp/ansible/fstab/{{ inventory_hostname }}{{ fstab_path }}"

并解析文件

  fstab: "{{ lookup('pipe', 'cat ' ~ fstab_local ~ ' | jc --fstab') }}"

给予

  fstab:
  - fs_file: /mountpoint1
    fs_freq: 0
    fs_mntops: mount-options
    fs_passno: 0
    fs_spec: Aaaaa:/mount1
    fs_vfstype: nfs
  - fs_file: /mountpoint4
    fs_freq: 0
    fs_mntops: mount-options
    fs_passno: 0
    fs_spec: Aaaaa:/mount2
    fs_vfstype: nfs
  - fs_file: /mountpoin9
    fs_freq: 0
    fs_mntops: mount-options
    fs_passno: 0
    fs_spec: Bbbbbn:/mount1
    fs_vfstype: nfs

声明您要更新的内容

    fstab_update:
      fs_spec: Aaaaa
      fs_mntops: new-mount-options

并更新 fstab

    fstab_new: |
      {% filter from_yaml %}
      {% for i in fstab %}
      {% if i.fs_spec is search(fstab_update.fs_spec) %}
      - {{ i|combine({'fs_mntops': fstab_update.fs_mntops}) }}
      {% else %}
      - {{ i }}
      {% endif %}
      {% endfor %}
      {% endfilter %}
    - debug:
        msg: |
          {% for i in fstab_new %}
          {{ fstab_labels|map('extract', i)|join(' ') }}
          {% endfor %}

给予

  msg: |-
    Aaaaa:/mount1 /mountpoint1 nfs new-mount-options 0 0
    Aaaaa:/mount2 /mountpoint4 nfs new-mount-options 0 0
    Bbbbbn:/mount1 /mountpoin9 nfs mount-options 0 0

更新文件

    - copy:
        dest: "{{ fstab_path }}"
        content: |
          {% for i in fstab_new %}
          {{ fstab_labels|map('extract', i)|join(' ') }}
          {% endfor %}

用于测试的完整剧本示例

- hosts: localhost

  vars:

    fstab_path: /tmp/fstab
    fstab_local: "/tmp/ansible/fstab/{{ inventory_hostname }}{{ fstab_path }}"
    fstab: "{{ lookup('pipe', 'cat ' ~ fstab_local ~ ' | jc --fstab') }}"

    fstab_labels: [fs_spec, fs_file, fs_vfstype, fs_mntops, fs_freq, fs_passno]
    fstab_update:
      fs_spec: Aaaaa
      fs_mntops: new-mount-options

    fstab_new: |
      {% filter from_yaml %}
      {% for i in fstab %}
      {% if i.fs_spec is search(fstab_update.fs_spec) %}
      - {{ i|combine({'fs_mntops': fstab_update.fs_mntops}) }}
      {% else %}
      - {{ i }}
      {% endif %}
      {% endfor %}
      {% endfilter %}

  tasks:

    - fetch:
        src: "{{ fstab_path }}"
        dest: /tmp/ansible/fstab/

    - debug:
        var: fstab

    - debug:
        msg: |
          {% for i in fstab_new %}
          {{ fstab_labels|map('extract', i)|join(' ') }}
          {% endfor %}

    - copy:
        dest: "{{ fstab_path }}"
        content: |
          {% for i in fstab_new %}
          {{ fstab_labels|map('extract', i)|join(' ') }}
          {% endfor %}
      when: not dry_run|d(true)|bool
© www.soinside.com 2019 - 2024. All rights reserved.