首页 > 解决方案 > blockinline 模块不尊重 insertafter

问题描述

我正在使用一个任务在 ~/.bash_profile 中添加环境变量。第一个任务是添加 java、ant 和 oracle home,然后是 PATH,然后是其他不属于 PATH 的变量。

添加房屋的第一个任务:

- name: Add environment variables in bash_profile
  become: yes
  blockinfile:
    path: "{{ bash_profile }}"
    insertafter: "^# User specific environment and startup programs"
    content: export {{ item.env_name }}={{ item.env_dir }}
    marker: ""
    state: present
  with_items:
  - { env_name: "{{ ant_home }}", env_dir: "{{ ant_home_dir }}" }
  - { env_name: "{{ java_home }}", env_dir: "{{ java_home_dir }}" }
  - { env_name: "{{ oracle_home }}", env_dir: "{{ oracle_home_dir }}" }
  - { env_name: "{{ lib_path_home }}", env_dir: "{{ lib_path_home_dir }}" }

它按预期部署变量,在 bash 文件中已经可用的注释行之后插入

第二个任务专用于我创建行然后删除原始 PATH 的 PATH

- name: Add PATH variable
  become: yes
  lineinfile:
    path: "{{ bash_profile }}"
    regexp: '^\PATH=$PATH:$HOME/.local/bin:$HOME/bin'
    line: 'PATH=$PATH:$HOME/.local/bin:$HOME/bin:{{ ant_path_dir }}:{{ java_path_dir }}:{{ oracle_path_dir }}'

- name: remove PATH variable
  become: yes
  lineinfile:
    path: "{{ bash_profile }}"
    line: 'PATH=$PATH:$HOME/.local/bin:$HOME/bin'
    state: absent

这将获得 PATH 行,添加声明的 home 和 bin 并删除原始路径,因为它不会在原始路径之前添加任何内容,它会创建第二行

最后一项任务是我使用 blockinfile 模块遇到问题的任务,特别是在insertafter参数中

- name: Add the rest of the environment variables in bash_profile
  blockinfile:
    path: "{{ bash_profile }}"
    insertafter: "^PATH=$PATH:$HOME/.local/bin:$HOME/bin:$ANT_HOME/bin:$JAVA_HOME/bin:$ORACLE_HOME/bin"
    content: export {{ item.env_name_1 }}={{ item.env_dir_1 }}
    marker: ""
  with_items:
  - { env_name_1: "{{ dynamo_home }}", env_dir_1: "{{ dynamo_home_dir }}" }
  - { env_name_1: "{{ atgjre_home }}", env_dir_1: "{{ atgjre_home_dir }}" }
  - { env_name_1: "{{ weblogic_home }}", env_dir_1: "{{ weblogic_home_dir }}" }
  - { env_name_1: "{{ node_env_home }}", env_dir_1: "{{ node_env_home_dir }}" }
  - { env_name_1: "{{ endeca_home }}", env_dir_1: "{{ endeca_home_dir }}" }

有了这 3 个任务,我需要编辑 bash_profile 以添加所有必需的变量,文件的最后一个方面是:

ANT_HOME
JAVA_HOME
ORACLE_HOME

PATH:

REST OF THE HOMES

实际结果是:

ANT_HOME
JAVA_HOME
ORACLE_HOME

REST OF THE HOMES

PATH:

标签: ansible

解决方案


我建议进行一些更改:

1)使用lineinfile而不是blockinfile因为您不完全插入文本块。您不需要insertafter用于最终任务,因为此模块的默认行为是追加。

2) 使用regexp选项。这确保了幂等性,即如果需要的行存在,那么当您重新运行播放时,ansible 不会更改或添加这些行。您无需担心 bash_profile 会被大量条目污染。

3) 对于任务 2(“添加 PATH 变量”),添加insertbefore选项。只是为了确保您在export PATH声明之前有新路径。

对于 lininfile ansible 文档,请参阅:https ://docs.ansible.com/ansible/latest/modules/lineinfile_module.html?highlight=lineinfile

这是重构的游戏

---
- name: Bash profile play
  hosts: 127.0.0.1
  connection: local
  become_user: root
  become: yes
  tasks:
    - name: Add environment variables in bash_profile
      become: yes
      lineinfile:
        path: "{{ bash_profile }}"
        insertafter: "^# User specific environment and startup programs"
        regexp: "^export {{ item.env_name }}={{ item.env_dir }}"
        line: export {{ item.env_name }}={{ item.env_dir }}
        state: present
      with_items:
        - { env_name: "{{ java_home }}", env_dir: "{{ java_home_dir }}" }
        - { env_name: "{{ maven_home }}", env_dir: "{{ maven_home_dir }}" }

    - name: Add PATH variable
      become: yes
      lineinfile:
        path: "{{ bash_profile }}"
        insertbefore: "^export PATH"
        regexp: '^PATH=.+'
        line: 'PATH=$PATH:$HOME/bin:{{ java_path_dir }}:{{ maven_path_dir }}'

    - name: Add the rest of the environment variables in bash_profile
      lineinfile:
        path: "{{ bash_profile }}"
        regexp: "^export {{ item.env_name_1 }}={{ item.env_dir_1 }}"
        line: export {{ item.env_name_1 }}={{ item.env_dir_1 }}
        state: present
      with_items:
        - { env_name_1: "{{ dynamo_home }}", env_dir_1: "{{ dynamo_home_dir }}" }
        - { env_name_1: "{{ atgjre_home }}", env_dir_1: "{{ atgjre_home_dir }}" }
...

推荐阅读