您应该将任务的“loop_control”选项中的“loop_var”值设置为其他值,以避免变量

您应该将任务的“loop_control”选项中的“loop_var”值设置为其他值,以避免变量

我的环境:

# cat /etc/debian_version
11.7
# ansible-playbook --version
ansible-playbook [core 2.13.1]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.9/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110]
  jinja version = 3.1.2
  libyaml = True
#

以下任务是我的 Ansible 角色的一部分:

- name: _file - state:absent
  ansible.builtin.file:
    path: "{{ item.path }}"
    state: absent
  loop: "{{ find.files | flatten }}"
  register: file
  when: find.matched is defined and find.matched != 0

然而,我注意到一条警告信息:

[警告]:任务:XYZ:_file - state:absent:循环变量“item”已在使用中。您应该将任务选项loop_var中的值设置为其他值,以避免变量冲突和意外行为。loop_control

读了一些之后:

我将我的任务修改为如下形式:

- name: _file - state:absent
  ansible.builtin.file:
    path: "{{ item.path }}"
    state: absent
  loop: "{{ find.files | flatten }}"
  loop_control:
    label: "{{ item.path }}"
    loop_var: find
  register: file
  when: find.matched is defined and find.matched != 0

这个任务在我的角色中被调用两次,第一次运行正常,第二次则失败

TASK [XYZ : _file - state:absent] ******************************************************************************************************************************************************************************
[WARNING]: TASK: XYZ : _file - state:absent: The loop variable 'find' is already in use. You should set the `loop_var` value in the `loop_control` option for the task to something else to avoid variable
collisions and unexpected behavior.
failed: [127.0.0.1] (item=None) => {"ansible_loop_var": "find", "changed": false, "find": {"atime": 1683511713.8529496, "checksum": "ecd34202c34bf761e4c2c9800a39e18dffad5d9e", "ctime": 1683511714.972948, "dev": 2049, "gid": 0, "gr_name": "root", "inode": 150677, "isblk": false, "ischr": false, "isdir": false, "isfifo": false, "isgid": false, "islnk": false, "isreg": true, "issock": false, "isuid": false, "mode": "0644", "mtime": 1683511714.972948, "nlink": 1, "path": "tmp/FILE.CSV", "pw_name": "root", "rgrp": true, "roth": true, "rusr": true, "size": 642, "uid": 0, "wgrp": false, "woth": false, "wusr": true, "xgrp": false, "xoth": false, "xusr": false}, "msg": "Failed to template loop_control.label: 'item' is undefined", "skip_reason": "Conditional result was False"}

请指教。

答案1

目前还不清楚为什么需要(未记录的)外循环来注册变量物品。例如,给定树

shell> tree /tmp/test
/tmp/test
├── file1
├── file2
└── file3

下面的剧情

shell> cat pb.yml
- hosts: localhost

  tasks:

    - find:
        paths: /tmp/test
      register: find

    - file:
        path: "{{ item.path }}"
        state: absent
      loop: "{{ find.files }}"
      loop_control:
        label: "{{ item.path }}"

给出跑动--检查 --差异模式

shell> ansible-playbook -CD pb.yml

PLAY [localhost] ******************************************************************************

TASK [find] ***********************************************************************************
ok: [localhost]

TASK [file] ***********************************************************************************
--- before
+++ after
@@ -1,2 +1,2 @@
 path: /tmp/test/file3
-state: file
+state: absent

changed: [localhost] => (item=/tmp/test/file3)
--- before
+++ after
@@ -1,2 +1,2 @@
 path: /tmp/test/file2
-state: file
+state: absent

changed: [localhost] => (item=/tmp/test/file2)
--- before
+++ after
@@ -1,2 +1,2 @@
 path: /tmp/test/file1
-state: file
+state: absent

changed: [localhost] => (item=/tmp/test/file1)

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

笔记:

  • 如果你定义循环变量使用它。下面的任务给出了相同的结果
- file:
    path: "{{ my_loop_var.path }}"
    state: absent
  loop: "{{ find.files }}"
  loop_control:
    label: "{{ my_loop_var.path }}"
    loop_var: my_loop_var
  • 以下条件是多余的。删除它。当未找到任何内容时(查找匹配:0)文件列表为空(罚款.文件:[])并且无论如何都会跳过循环
  when: find.matched is defined and find.matched != 0
  • 如果寻找是模块的注册变量寻找. 过滤器压平可以删除
  loop: "{{ find.files }}"

相关内容