首页 > 解决方案 > 使用 ansible 在所有子目录中创建丢失的文件

问题描述

我想检查文件夹的所有子目录中是否有特定文件。如果文件不存在,我想创建它。这是我的剧本:

---
- hosts: localhost
  become: 'yes'
  vars:
    dir_path: "/tmp/test"
  tasks:
  - name: Find /tmp/test/ all directories
    find:
      paths: /tmp/test/
      recurse: no
      file_type: directory
    register: dir_list
  - debug: var=dir_list
  - name: check if test file exists
    stat:
      path:  "{{ dir_list.files | map(attribute='path') }}/test.txt"
    register:  file_exists
    loop: "{{ dir_list.files | map(attribute='path') | list }}"
  - name: create file
    shell: touch {{ files_exists.item }}/test.txt
    register: create_file
    when: not file_exists.stat.exists
    loop: "{{ file_exists.item }} | list }}"

但是“创建文件”失败了,知道如何解决这个问题吗?

标签: loopsansible

解决方案


您在最后一个任务中的使用是错误的:在检查文件是否存在时,loop您没有使用在迭代期间创建的。item

(注意您的下一个问题:避免单独使用诸如“它失败”或“它不起作用”之类的句子,因为它们不能准确地描述您的问题

在您的示例中,您正在尝试使用仅为此目的制作shell的模块来创建文件。file我在下面的示例中使用了它:

剧本:

---
- name: Create missing file in subdirs
  hosts: localhost
  gather_facts: false

  vars:
    dir_path: "/tmp/test"
    file_name: "test.txt"

  tasks:
    - name: "Find subdirs in {{ dir_path }}"
      find:
        paths: "{{ dir_path }}"
        recurse: no
        file_type: directory
      register: dir_list

    - name: "Show result of dir listing "
      debug:
        var: dir_list
        verbosity: 1

    - name: "Check if {{ file_name }} exists in subdirs"
      stat:
        path: "{{ item }}/{{ file_name }}"
      register: file_check
      loop: "{{ dir_list.files | map(attribute='path') | list }}"

    - name: "Show the file check result"
      debug:
        var: file_check
        verbosity: 1

    - name: "Create file where it does not exist"
      file:
        path: "{{ item }}/{{ file_name }}"
        state: touch
      loop: "{{ file_check.results | rejectattr('stat.exists') | map(attribute='item') | list }}"

哪个给出(用于ansible-playbook -v查看verbosity: 1调试任务)

# Create test dir and subdirs
$ for d in {a..d}; do mkdir -p /tmp/test/$d; done

# Add the test file in one dir for demo
$ touch /tmp/test/c/test.txt

# Show the situation before running the playbook
$ tree /tmp/test/
/tmp/test/
├── a
├── b
├── c
│   └── test.txt
└── d

4 directories, 1 file

# Run the playbook (run with debug for yourself if you wish)
$ ansible-playbook play.yml

PLAY [Create missing file in subdirs] *****************************************************************************************************************************************************************************

TASK [Find subdirs in /tmp/test] **********************************************************************************************************************************************************************************
ok: [localhost]

TASK [Show result of dir listing] *********************************************************************************************************************************************************************************
skipping: [localhost]

TASK [Check if test.txt exists in subdirs] ************************************************************************************************************************************************************************
ok: [localhost] => (item=/tmp/test/a)
ok: [localhost] => (item=/tmp/test/b)
ok: [localhost] => (item=/tmp/test/c)
ok: [localhost] => (item=/tmp/test/d)

TASK [Show the file check result] *********************************************************************************************************************************************************************************
skipping: [localhost]

TASK [Create file where it does not exist] ************************************************************************************************************************************************************************
changed: [localhost] => (item=/tmp/test/a)
changed: [localhost] => (item=/tmp/test/b)
changed: [localhost] => (item=/tmp/test/d)

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0

# Check the result
$ tree /tmp/test/
/tmp/test/
├── a
│   └── test.txt
├── b
│   └── test.txt
├── c
│   └── test.txt
└── d
    └── test.txt

4 directories, 4 files

# Run the playbook again to demonstrate idempotency
$ ansible-playbook play.yml

PLAY [Create missing file in subdirs] *****************************************************************************************************************************************************************************

TASK [Find subdirs in /tmp/test] **********************************************************************************************************************************************************************************
ok: [localhost]

TASK [Show result of dir listing] *********************************************************************************************************************************************************************************
skipping: [localhost]

TASK [Check if test.txt exists in subdirs] ************************************************************************************************************************************************************************
ok: [localhost] => (item=/tmp/test/a)
ok: [localhost] => (item=/tmp/test/b)
ok: [localhost] => (item=/tmp/test/c)
ok: [localhost] => (item=/tmp/test/d)

TASK [Show the file check result] *********************************************************************************************************************************************************************************
skipping: [localhost]

TASK [Create file where it does not exist] ************************************************************************************************************************************************************************

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0

推荐阅读