I'm trying to use the result of Ansible find command, which return list of files it find on a specific folder, the problem is, when I iterate over the result, I do not have the file names, I only have their full paths (including the name), is there an easy way to use the result item below to provide the file_name in the second command as shown below?
- name: get files
find:
paths: /home/me
file_type: "file"
register: find_result
- name: Execute docker secret create
shell: docker secret create <file_name> {{ item.path }}
run_once: true
with_items: "{{ find_result.files }}"
basename
filter?
{{ item.path | basename }}
There are also dirname
, realpath
, relpath
filters.
This question and accepted answer are great for the time they were written. However, I want to leave a note about the current preferred way of doing it.
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#migrating-to-loop
With the release of Ansible 2.5, the recommended way to perform loops is the use the new loop keyword instead of with_X style loops.
I've seen seen this common pattern evolve for such file-loop combinations.
- name: "Find python files in folder scripts"
find:
paths: "{{ playbook_dir }}/scripts"
patterns: "*.py"
file_type: "file"
register: python_files
- name: "Execute those python scripts from the script folder"
shell: "python {{ item.path | basename }}"
args:
chdir: "{{ playbook_dir }}/scripts"
loop: "{{ python_files.files }}"
loop_control:
label: "{{ item.path | basename }}"
This loops over a certain type of files in a directory (python files) and takes a certain action with their filename (executes them), and using their filename is justified because chdir
puts you in the directory where those files are.
It's important to use that same filename in loop_control
because otherwise it prints item
, which isn't just the absolute path, but a dozen other file properties which is completely unreadable.
This works, but it also ignores the motivations for the loop
changes to Ansible in the first place. This also works, replacing 2 tasks with 1:
- name: "Execute python scripts from the script folder"
shell: "python {{ item | basename }}"
args:
chdir: "{{ playbook_dir }}/scripts"
with_fileglob: "{{ playbook_dir }}/scripts/*.py"
loop_control:
label: "{{ item | basename }}"
In this loop, item
is the absolute path. You may prefer to print that, in which case lose the loop_control
completely.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With