Ansible:如何用with_sequence循环多同长度数组的索引并调用元素?
你提到的两处问题确实是关键错误,另外还有一处容易忽略的索引越界问题,我来帮你逐一修正并提供更优的遍历方案:
核心错误点解析
嵌套双大括号误用:在Jinja2表达式内部(已经在
{{ }}里了),不需要再嵌套{{ }}。比如SERIAL_NUMBER[{{ item }}]是错误写法,直接写SERIAL_NUMBER[item|int]即可(因为with_sequence返回的是字符串类型,需要转为整数索引)。When条件写法错误:Ansible的
when参数本身支持直接写Jinja2表达式,不需要额外用{{ }}包裹。正确写法是when: LICENSE_TYPE == "evaluation",而不是when: "{{ LICENSE_TYPE }}" == "evaluation"。索引越界风险:
with_sequence的end值设置为{{ SERIAL_NUMBER|length }}会导致最后一次循环取到索引3(假设数组长度是3),但数组的最大索引是2,这会触发数组越界错误。正确的end值应该是{{ SERIAL_NUMBER|length - 1 }}。
修正后的基础版本代码
tasks: - name: Set facts set_fact: SERIAL_NUMBER: ['2342', '4455', '5643'] PASSWORD: ['xxx', 'yyy', 'zzz'] EXP_DATE: ['06-10-18', '07-01-19', '06-01-18'] LICENSE_TYPE: "evaluation" - name: Execute the script to apply evaluation license lineinfile: dest: "/root/test.txt" line: "{{ SERIAL_NUMBER[item|int] }} {{ PASSWORD[item|int] }} {{ EXP_DATE[item|int] }}" create: yes with_sequence: start=0 end={{ SERIAL_NUMBER|length - 1 }} when: LICENSE_TYPE == "evaluation"
更优的遍历方案:使用zip过滤器打包数组
Ansible提供了zip过滤器,可以将多个长度相同的数组按索引打包成元组,这样遍历起来更直观,完全避免索引操作的错误:
tasks: - name: Set facts set_fact: SERIAL_NUMBER: ['2342', '4455', '5643'] PASSWORD: ['xxx', 'yyy', 'zzz'] EXP_DATE: ['06-10-18', '07-01-19', '06-01-18'] LICENSE_TYPE: "evaluation" - name: Execute the script to apply evaluation license lineinfile: dest: "/root/test.txt" line: "{{ item.0 }} {{ item.1 }} {{ item.2 }}" create: yes with_together: - "{{ SERIAL_NUMBER }}" - "{{ PASSWORD }}" - "{{ EXP_DATE }}" when: LICENSE_TYPE == "evaluation"
这里with_together会把三个数组中对应索引的元素打包成元组,比如第一个元组是('2342', 'xxx', '06-10-18'),遍历的时候直接通过item.0、item.1、item.2获取对应值,代码可读性更高,也不会出现索引越界的问题。
内容的提问来源于stack exchange,提问作者Prabhakar Arasavelli

