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

Ansible脚本执行报set类型对象无法JSON序列化如何解决

错误根因

Ansible的unique过滤器仅针对列表类型输入返回列表,若传入字符串、数字等非列表非None值,会直接返回set类型,而set无法被JSON序列化,因此触发报错。你之前用字符串替换把None转空列表的方案属于临时适配,没有覆盖非列表有效值的场景,所以遇到Name: D的配置就会出错。

修复方案

不需要提前做replace字符串替换,直接在循环的变量定义处增加类型判断逻辑,统一把source、dest的值标准化为列表后再去重,即可覆盖所有场景:

- set_fact:
    out: "{{ out|d([]) + [{'Name': item.Name,
                           'source': _src,
                           'dest': _dst}] }}"
  loop: "{{ output }}"
  vars:
    # 统一标准化source为列表类型
    _src_list: >-
      {% if item.source is iterable and item.source is not string and item.source is not mapping %}
      {{ item.source }}
      {% elif item.source is none %}
      []
      {% else %}
      [{{ item.source }}]
      {% endif %}
    _src: "{{ _src_list | unique }}"
    # 统一标准化dest为列表类型
    _dst_list: >-
      {% if item.dest is iterable and item.dest is not string and item.dest is not mapping %}
      {{ item.dest }}
      {% elif item.dest is none %}
      []
      {% else %}
      [{{ item.dest }}]
      {% endif %}
    _dst: "{{ _dst_list | unique }}"
- debug:
    var: out

逻辑说明

  • 首先判断输入值是否为「纯列表类型」:可迭代但排除字符串、字典类型,符合条件则直接使用原值
  • 若输入为None,直接返回空列表,替代之前的字符串替换方案,不会误伤包含None字符串的合法值
  • 其他非列表的有效值(比如Name:D配置中的字符串"1.2"、"x")会被包装为单元素列表,再调用unique过滤器会返回列表而非set,彻底解决序列化报错问题

处理后所有配置的输出结果均符合预期:

  • Name:A的source去重后为["a", "b", "c"],dest去重后为["x", "y", "z"]
  • Name:B的source去重后为["a", "b", "c"],dest去重后为["x.c", "y", "z", "x"]
  • Name:C的source和dest均为[]
  • Name:D的source为["1.2"],dest为["x"]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 11:06:01