Dominik
Dominik

Reputation: 141

Ansible "lineinfile": add new line (with PATH=) or append to existing line (with PATH=)

I am trying to replace or append a path part to the path definition in /etc/environment on a linux box.

Here's what I have:

//all.yml
my_path: "/usr/bin:/usr/sbin"
my_extra_path: "/usr/extra/path"

In my role-file:

//updatePath.yml
- name: update /etc/environment
  lineinfile:
    dest=/etc/environment
    state=present
    backrefs=yes
    regexp='PATH=({{ my_path }}:?)?({{ my_extra_path }}:?)?(.*)'
    line='PATH={{ my_extra_path }}:{{ my_extra_path }}:\3'

Now when I run the role, it works fine updating an existing PATH-line, but not creating duplicates within the line or even duplicate lines. So far so good.

When there is no line with "PATH=" present, I would expect it to add a new one. But it doesn't.

Is my expectation wrong or where lies the problem?

Upvotes: 3

Views: 13580

Answers (2)

Je.Go
Je.Go

Reputation: 81

Same idea as here : https://stackoverflow.com/a/40890850/7231194 or here : https://stackoverflow.com/a/40891927/7231194

Steps are:

  • Try to replace the line.
  • If replace mod change it. Cool, it's over !
  • If replace mod doesn't change, add the line

Example

# Vars
- name: Set parameters
  set_fact:
    my_path: "/usr/bin:/usr/sbin"
    my_extra_path: "/usr/extra/path"

# Tasks
- name: Try to replace the line if it exists
  replace:
    dest    : /dir/file
    replace : 'PATH={{ my_extra_path }}'
    regexp  : '^PATH=.*'
    backup  : yes
  register  : tryToReplace

# If the line not is here, I add it
- name: Add line
  lineinfile:
    state   : present
    dest    : /dir/file
    line    : '{{ my_extra_path }}'
    regexp  : ''
    insertafter: EOF
  when: tryToReplace.changed == false

Upvotes: 2

MillerGeek
MillerGeek

Reputation: 3137

You are using the backrefs: true flag, which prevents lineinfile from changing the file if the line does not already exist. From the docs:

Used with state=present. If set, line can contain backreferences (both positional and named) that will get populated if the regexp matches. This flag changes the operation of the module slightly; insertbefore and insertafter will be ignored, and if the regexp doesn't match anywhere in the file, the file will be left unchanged. If the regexp does match, the last matching line will be replaced by the expanded line parameter.

Since you need to create the line if it does not exist, you should use:

- name: Check whether /etc/environment contains PATH
  command: grep -Fxq "PATH=" /etc/environment
  register: checkpath
  ignore_errors: True
  changed_when: False

//updatePath.yml
- name: Add path to /etc/environment
  lineinfile:
    dest=/etc/environment
    state=present
    regexp='^PATH='
    line='PATH={{ my_extra_path }}'
  when: not checkpath.rc == 0

- name: update /etc/environment
  lineinfile:
    dest=/etc/environment
    state=present
    backrefs=yes
    regexp='PATH=({{ my_path }}:?)?({{ my_extra_path }}:?)?(.*)'
    line='PATH={{ my_extra_path }}:{{ my_extra_path }}:\3'
  when: checkpath.rc == 0

Upvotes: 5

Related Questions