Ansible:with_items循环中无法向列表追加元素问题咨询
解决Ansible循环中列表无法正确追加的问题
这个问题我之前也碰到过,核心原因是Ansible在执行任务前会预先渲染所有变量表达式,所以你循环里的final_list + [{'key': item}],每次迭代都是基于最开始定义的空列表[]来计算,而不是上一次循环更新后的final_list值,最后自然只会保留最后一次迭代的结果。
下面给你两种可靠的解决方法:
方法1:利用register收集循环结果再构建列表
这种方法更清晰,也更容易调试,先把每个迭代生成的字典存下来,最后再合并成列表:
- hosts: localhost gather_facts: no vars: in_list: - value1 - value2 - value3 tasks: - debug: var: in_list - name: 生成每个元素对应的字典 set_fact: single_dict: "{{ {'key': item} }}" with_items: "{{ in_list }}" register: generated_dicts - name: 构建最终列表 set_fact: final_list: "{{ generated_dicts.results | map(attribute='ansible_facts.single_dict') | list }}" - debug: var: final_list
执行后final_list会正确得到:
final_list: - {key: value1} - {key: value2} - {key: value3}
方法2:修改set_fact的变量引用方式
直接在循环里使用final_list | default([])来获取当前最新的列表值(如果还没初始化就用空列表),这样每次迭代都会基于上一次的结果追加:
- hosts: localhost gather_facts: no vars: in_list: - value1 - value2 - value3 tasks: - debug: var: in_list - name: 逐次追加列表元素 set_fact: final_list: "{{ final_list | default([]) + [{'key': item}] }}" with_items: "{{ in_list }}" - debug: var: final_list
注意这里可以删掉原来定义的final_list: [],或者保留也没关系,default([])会优先取已有的值。
为什么原来的写法不行?
再啰嗦一句:Ansible的任务变量渲染是任务级别的,也就是说在set_fact任务开始执行前,所有迭代里的final_list都会被替换成初始的空列表,所以每个迭代实际上都是在做[] + [{'key': item}],最后一次的结果会覆盖之前所有的设置,这就是你看到的只保留最后一个元素的原因。
内容的提问来源于stack exchange,提问作者ilias-sp
相关产品推荐
相关产品推荐

