How do I loop over each line inside a file with an

2020-03-09 08:25发布

问题:

I am looking for something that would be similar to with_items: but that would get the list of items from a file instead of having to include it in the playbook file.

How can I do this in ansible?

回答1:

I managed to find an easy alternative:

- debug: msg="{{item}}"
  with_lines: cat files/branches.txt


回答2:

Lets say you have a file like

item 1
item 2
item 3

And you want to install these items.Simply get the file contents to a variable using register.And use this variable for with_items. Make sure your file has one item per line.

---
- hosts: your-host
  remote_user: your-remote_user
  tasks:
  - name: get the file contents
    command: cat /path/to/your/file
    register: my_items
  - name: install these items
    pip: name:{{item}}
    with_items: my_items.stdout_lines


回答3:

I am surprised that nobody mentioned the ansible Lookups, I think that is exactly what you want.

It reads contents that you want to use in your playbook but do not want to include inside the playbook from files, pipe, csv, redis etc from your local control machine(not from remote machine, that is important, since in most cases, these contents are alongside your playbook on your local machine), and it works with ansible loops.

---
- hosts: localhost
  gather_facts: no
  tasks:
    - name: Loop over lines in a file
      debug:
        var: item
      with_lines: cat "./files/lines"

with_lines here is actually loop with lines lookup, to see how the lines lookup works, see the code here, it just runs any commands you give it(so you can give it any thing like echo, cat etc), then split the output into lines and return them.

There are many powerful lookups, to get the comprehensive list, check out the lookup plugins folder.



回答4:

Latest Ansible recommends loop instead of with_something. It can be used in combination with lookup and splitlines(), as Ikar Pohorský pointed out:

- debug: msg="{{item}}"
  loop: "{{ lookup('file', 'files/branches.txt').splitlines() }}"

files/branches.txt should be relative to the playbook