Only check whether a line present in a file (ansible)

后端 未结 8 1995
粉色の甜心
粉色の甜心 2020-12-01 02:36

In ansible, I need to check whether a particular line present in a file or not. Basically, I need to convert the following command to an ansible task. My goal is to only che

相关标签:
8条回答
  • 2020-12-01 03:02

    Use check_mode, register and failed_when in concert. This fails the task if the lineinfile module would make any changes to the file being checked. Check_mode ensures nothing will change even if it otherwise would.

    - name: "Ensure /tmp/my.conf contains '127.0.0.1'"
      lineinfile:
        name: /tmp/my.conf
        line: "127.0.0.1"
        state: present
      check_mode: yes
      register: conf
      failed_when: (conf is changed) or (conf is failed)
    
    0 讨论(0)
  • 2020-12-01 03:11

    User robo's regexp & absent method is quite clean, so I've fleshed it out here for easy use and added improvements from comments by @assylias and @Olivier:

    - name: Ensure /tmp/my.conf contains 127.0.0.1
      lineinfile:
        path: /tmp/my.conf
        regexp: '^127\.0\.0\.1.*whatever'
        state: absent
      check_mode: yes
      changed_when: false
      register: out
    
    - debug:
        msg: "Yes, line exists."
      when: out.found
    
    - debug:
        msg: "Line does NOT exist."
      when: not out.found
    
    0 讨论(0)
  • 2020-12-01 03:11

    You can use the file plugin for this scenario.

    To set a fact you can use in other tasks ... this works.

    - name: Check whether /tmp/my.conf contains "127.0.0.1"
      set_fact:
        myconf: "{{ lookup('file', '/tmp/my.conf') }}"  
      ignore_errors: yes
    
    - name: Greet the world if /tmp/my.conf contains "127.0.0.1"
      debug: msg="Hello, world!"
      when: "'127.0.0.1' in myconf"
    

    To check the file content as a condition of a task ... this should work.

    - name: Greet the world if /tmp/my.conf contains "127.0.0.1"
      debug: msg="Hello, world!"
      when: "'127.0.0.1' in lookup('file', '/tmp/my.conf')"
    
    0 讨论(0)
  • With the accepted solution, even though you ignore errors, you will still get ugly red error output on the first task if there is no match:

    TASK: [Check whether /tmp/my.conf contains "127.0.0.1"] ***********************
    failed: [localhost] => {"changed": false, "cmd": "grep -Fxq "127.0.0.1" /tmp/my.conf", "delta": "0:00:00.018709", "end": "2015-09-27 17:46:18.252024", "rc": 1, "start": "2015-09-27 17:46:18.233315", "stdout_lines": [], "warnings": []}
    ...ignoring
    

    If you want less verbose output, you can use awk instead of grep. awk won't return an error on a non-match, which means the first check task below won't error regardless of a match or non-match:

    - name: Check whether /tmp/my.conf contains "127.0.0.1"
      command: awk /^127.0.0.1$/ /tmp/my.conf
      register: checkmyconf
      changed_when: False
    
    - name: Greet the world if /tmp/my.conf contains "127.0.0.1"
      debug: msg="Hello, world!"
      when: checkmyconf.stdout | match("127.0.0.1")
    

    Notice that my second task uses the match filter as awk returns the matched string if it finds a match.

    The alternative above will produce the following output regardless of whether the check task has a match or not:

    TASK: [Check whether /tmp/my.conf contains "127.0.0.1"] ***********************
    ok: [localhost]
    

    IMHO this is a better approach as you won't ignore other errors in your first task (e.g. if the specified file did not exist).

    0 讨论(0)
  • 2020-12-01 03:14
    - name: Check whether /tmp/my.conf contains "127.0.0.1"
      command: grep -Fxq "127.0.0.1" /tmp/my.conf
      register: checkmyconf
      check_mode: no
      ignore_errors: yes
      changed_when: no
    
    - name: Greet the world if /tmp/my.conf contains "127.0.0.1"
      debug: msg="Hello, world!"
      when: checkmyconf.rc == 0
    

    Update 2017-08-28: Older Ansible versions need to use always_run: yes instead of check_mode: no.

    0 讨论(0)
  • 2020-12-01 03:17

    Another way is to use the "replace module" then "lineinfile module".

    The algo is closed to the one used when you want to change the values of two variables.

    • First, use "replace module" to detect if the line you are looking for is here and change it with the something else. (Like same line + something at the end).
    • Then if "replace" is true, It means your line is here then replace the new line with a particularity, with the new line looking.
    • Else the line you are looking for is not here.

    Example:

    # Vars
    - name: Set parameters
      set_fact:
        newline      : "hello, i love ansible"
        lineSearched : "hello"
        lineModified : "hello you"
    
    # Tasks
    - name: Try to replace the line
      replace:
        dest    : /dir/file
        replace : '{{ lineModified }} '
        regexp  : '{{ lineSearched }}$'
        backup  : yes
      register  : checkIfLineIsHere
    
    - name: Line is here, change it
      lineinfile:
        state   : present
        dest    : /dir/file
        line    : '{{ newline }}'
        regexp  : '{{ lineModified }}$'
      when: checkIfLineIsHere.changed
    
    • If the file contains "hello", it will become "hello you" then "hello, i love ansible" at the end.
    • If the file content doesn't contain "hello", the file is not modified.

    With the same idea, you can do something if the lineSearched is here:

    # Vars
    - name: Set parameters
      set_fact:
        newline      : "hello, i love ansible"
        lineSearched : "hello"
        lineModified : "hello you"
    
    # Tasks
    - name: Try to replace the line
      replace:
        dest    : /dir/file
        replace : '{{ lineModified }} '
        regexp  : '{{ lineSearched }}$'
        backup  : yes
      register  : checkIfLineIsHere
    
    # If the line is here, I want to add something.
    - name: If line is here, do something
      lineinfile:
        state   : present
        dest    : /dir/file
        line    : '{{ newline }}'
        regexp  : ''
        insertafter: EOF
      when: checkIfLineIsHere.changed
    
    # But I still want this line in the file, Then restore it
    - name: Restore the searched line.
      lineinfile:
        state   : present
        dest    : /dir/file
        line    : '{{ lineSearched }}'
        regexp  : '{{ lineModified }}$'
      when: checkIfLineIsHere.changed
    
    • If the file contains "hello", the line will still contain "hello" and "hello, i love ansible" at the end.
    • If the file content doesn't contain "hello", the file is not modified.
    0 讨论(0)
提交回复
热议问题