条件下的 Ansible 循环中断

Ansible loop break at condition

我需要符合特定条件的第一件商品。例如,在这种情况下,我想要 'banana',第一个状态为:true 的项目。示例剧本:

- hosts: localhost
  vars:
    my_fruit:
    fruits: [
      {state: false, fruit: apple},
      {state: true, fruit: banana},
      {state: true, fruit: orange},
      {state: false, fruit: pear}
    ]
  tasks:
    - name: get first fruit with state = true.
      set_fact:
        my_fruit: "{{ item.fruit }}"
      loop: "{{ fruits }}"
      when: 
        - item.state == true
        - my_fruit == ''

    - name: Check true fruit.
      debug:
        var: my_fruit

输出为:

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

TASK [Gathering Facts] **************************************************************************************************************************************************************************************
ok: [localhost]

TASK [get first fruit with state = true.] *******************************************************************************************************************************************************************
skipping: [localhost] => (item={'state': False, 'fruit': 'apple'}) 
skipping: [localhost] => (item={'state': True, 'fruit': 'banana'}) 
skipping: [localhost] => (item={'state': True, 'fruit': 'orange'}) 
skipping: [localhost] => (item={'state': False, 'fruit': 'pear'}) 

TASK [Check true fruit.] ************************************************************************************************************************************************************************************
ok: [localhost] => {
    "my_fruit": null
}

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

my_fruit 结果为空,如果我跳过 - my_fruit == '' 条件,结果是 'orange':

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

TASK [Gathering Facts] **************************************************************************************************************************************************************************************
ok: [localhost]

TASK [get first fruit with state = true.] *******************************************************************************************************************************************************************
skipping: [localhost] => (item={'state': False, 'fruit': 'apple'}) 
ok: [localhost] => (item={'state': True, 'fruit': 'banana'})
ok: [localhost] => (item={'state': True, 'fruit': 'orange'})
skipping: [localhost] => (item={'state': False, 'fruit': 'pear'}) 

TASK [Check true fruit.] ************************************************************************************************************************************************************************************
ok: [localhost] => {
    "my_fruit": "orange"
}

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

我怎样才能得到'banana'?

谢谢!

问题是因为您将变量 "my_fruit" 初始化为 null 而不是空字符串(您的条件“my_fruit == ''”正在测试变量是空字符串还是不是)这就是剧本跳过你的整个列表的原因。我建议您将变量初始化为 my_fruit: '',它应该可以工作

TASK [get first fruit with state = true.] ****************************************************************************************************************************
skipping: [localhost] => (item={'state': False, 'fruit': 'apple'}) 
ok: [localhost] => (item={'state': True, 'fruit': 'banana'})
skipping: [localhost] => (item={'state': True, 'fruit': 'orange'}) 
skipping: [localhost] => (item={'state': False, 'fruit': 'pear'}) 

TASK [Check true fruit.] *********************************************************************************************************************************************
ok: [localhost] => {
    "my_fruit": "banana"
}

试试这个

    - set_fact:
        my_fruit: "{{ (fruits|selectattr('state')|first).fruit }}"

详情:

  • selectattr"If no test is specified, the attribute’s value will be evaluated as a boolean."

  • 可以在列表中使用索引,而不是过滤器 first

        my_fruit: "{{ (fruits|selectattr('state')|list).0.fruit }}"