所以我最近很沮丧,因为使用Ansible对文件列表进行简单的查找和更改权限是多么困难。我通过两种方式实现了这一点,都很有效,但我想知道是否有人有更好的方法。
我的第一个方法,我只是要求Ansible做和我在bash中做的相同的事情,就像这样:
tasks:
- shell: ls -1 "{{ SomeDir }}"
register: file_names
- command: chmod 754 "{{ SomeDir }}/{{ item }}"
loop: "{{ file_names.stdout_lines }}"
我今天回到这里,试图找到一种更可靠的本地方式来完成任务,并想出了这个方法,但对于这样一个简单的任务来说,它似乎太笨重了:
tasks:
- name: "Find all files in the directory"
find:
paths: "{{ SomeDir }}"
file_type: file
register : find_output
- name: "loop through the .files output and then pick out the .path attribute"
file:
path: "{{ item.path }}"
mode: '0754'
loop:
"{{ find_output.files }}"
正如你所看到的,我不擅长输出操作。如果我能做一些类似{{ find_output.files.path }}
的事情,我会很高兴的,但我无法让查找或压平操作正常工作,也许有人可以纠正我的错误。
这只是一个简化它的想法,因为如果我理解得当,你只是想以非递归的方式更改文件夹中的所有文件权限
要实现这一点,还可以使用fileglob
查找及其等效的with_fileglob
结构。
有效地将两项任务合二为一:
- file:
path: "{{ item }}"
mode: "0754"
with_fileglob: "{{ SomeDir }}/*"
如果您想从复杂的字典列表中创建一个简单的列表,就像file
模块为您提供的一样,您可以使用map
和list
过滤器的组合。
以下是实现这一目标的示例:
- hosts: all
gather_facts: no
tasks:
- debug:
msg: "{{ faked_find_output.files | map(attribute='path') | list }}"
vars:
faked_find_output:
changed: false
failed: false
files:
- gid: 0
uid: 0
path: /path/to/file1
size: 0
- gid: 0
uid: 0
path: /path/to/file2
size: 0
这产生:
PLAY [all] ********************************************************************************************************
TASK [debug] ******************************************************************************************************
ok: [localhost] => {
"msg": [
"/path/to/file1",
"/path/to/file2"
]
}
PLAY RECAP ********************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
但请注意,这将不适用于您的用例,因为file
模块不接受path
的列表。
所以在你的情况下,你能做的最好的事情是:
- file:
path: "{{ item }}"
mode: "0754"
loop: "{{ find_output.files | map(attribute='path') | list }}"
但是,老实说,这只是毫无理由地增加复杂性。