You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ansible Jinja模板中用单个for循环同时遍历两个列表

问题原因

你写的for validator_ip,validator in 列表1,列表2属于Jinja2的并行遍历语法,要求两个遍历的列表长度完全一致,每次循环分别取两个列表相同位置的元素赋值,你的两个列表长度不匹配才会抛出解包错误,而且这个逻辑本身就不能实现把两个列表所有元素都拼接的需求。

可行实现方案

推荐使用Jinja2列表推导实现,代码简洁易读,不需要额外的循环边界判断:

#!/bin/sh

/usr/local/bin/haproxy-ea-health-check \
  -reference-servers="{{
    [
      for ip in trusted_validators_ips | difference([ansible_default_ipv4.address])
      : 'http://' ~ ip ~ ':9100'
    ] + [
      for h in groups[network+'_reference'] | difference([inventory_hostname])
      : 'http://' ~ hostvars[h].hostname ~ '.' ~ hostvars[h].domainname ~ ':9100'
    ] | join(',')
  }}" \

如果习惯使用传统for循环写法,也可以用分段循环的方式实现:

#!/bin/sh
{% set cleaned_ips = trusted_validators_ips | difference([ansible_default_ipv4.address]) %}
{% set cleaned_hosts = groups[network+'_reference'] | difference([inventory_hostname]) %}
/usr/local/bin/haproxy-ea-health-check \
  -reference-servers="{% for ip in cleaned_ips %}http://{{ ip }}:9100{% if not loop.last %},{% endif %}{% endfor %}{% if cleaned_ips | length > 0 and cleaned_hosts | length > 0 %},{% endif %}{% for h in cleaned_hosts %}http://{{ hostvars[h].hostname }}.{{ hostvars[h].domainname }}:9100{% if not loop.last %},{% endif %}{% endfor %}" \
渲染效果

两种写法最终都会输出你需要的合并后的参数格式:

#!/bin/sh

/usr/local/bin/haproxy-ea-health-check \
  -reference-servers="http://192.168.1.200:9100,http://192.168.1.201:9100,http://192.168.1.202:9100,http://192.168.1.203:9100,http://server1.domain.com:9100,http://server2.domain.com:9100,http://server3.domain.com:9100" \

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 09:27:03