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

Ansible set_fact任务报类型错误:期望字符串却得到列表,如何解决?

问题:Ansible Playbook处理userdata字典列表时的类型错误解决

需求与现有代码

需要对userdata(由字典组成的列表)进行处理,去除所有键和值的首尾空格,得到处理后的字典列表用于后续生成CSV。现有Playbook代码如下:

- hosts: localhost

  tasks:
    - set_fact:
        userdata: |
          {% filter from_yaml %}
          {% for i in userdata %}
          {% set keys=i.keys()|map('trim') %}
          {% set values=i.values()|map('trim') %}
          - {{ dict(keys|zip(values)) }}
          {% endfor %}
          {% endfilter %}

错误信息

执行时出现类型错误:

{"msg": "Unexpected templating type error occurred on ({% filter from_yaml %}
{% for i in userdata %}
{% set keys=i.keys()|map('trim') %}
{% set vals=i.values()|map('trim') %}
- {{ dict(keys|zip(vals)) }}
{% endfor %}
{% endfilter %}
): sequence item 0: expected str instance, list found"}

移除{% filter from_yaml %}后,userdata会变成YAML格式的字符串,不符合后续处理需求。

原始userdata结构

{
  "userdata": [
    {
      "ClassType": "Part Time",
      "Code": " #3091 ",
      "DateofSubmission": " 14/5/2023 ",
      "Description": "NIL",
      "FirstName": " Peter ",
      "LastName": " Miller ",
      "path": "OU=fulltime,OU=Test OU,DC=localdemo,DC=local"
    },
    {
      "ClassType": "Full Time",
      "Code": " #3092 ",
      "DateofSubmission": " 2/5/2023 ",
      "Description": "NIL",
      "FirstName": " Sam ",
      "LastName": " Keller ",
      "path": "OU=parttime,OU=Test OU,DC=localdemo,DC=local"
    },
    {
      "ClassType": "Flexi",
      "Code": " #3093 ",
      "DateofSubmission": " 10/5/2023 ",
      "Description": "NIL",
      "FirstName": " Judy ",
      "LastName": " Higgins ",
      "path": "OU=flexi,OU=Test OU,DC=localdemo,DC=local"
    }
  ]
}

解决方案

错误原因

原有写法错误地将Python字典对象直接渲染为字符串,再通过from_yaml解析。但dict(keys|zip(values))输出的是Python字典的字符串表示(如{'key': 'val'}),而非标准YAML映射格式(如key: val),导致YAML解析时出现类型不匹配。

优化后的Playbook

直接通过Ansible过滤器链生成处理后的字典列表,无需经过YAML字符串转换:

- hosts: localhost
  tasks:
    - set_fact:
        userdata: "{{ userdata | map('items') | map('map', 'trim') | map('dict') | list }}"

过滤器链说明

  • map('items'):将每个字典转换为(key, value)元组列表
  • map('map', 'trim'):对每个元组中的键和值都执行首尾空格去除
  • map('dict'):将处理后的元组列表重新转换为字典
  • list:将迭代器转换为最终的列表结构

备选写法(显式循环)

如果需要更直观的逻辑,也可以用显式循环构建处理后的列表:

- hosts: localhost
  tasks:
    - set_fact:
        userdata: >-
          {% set processed_list = [] %}
          {% for item in userdata %}
            {% set trimmed_dict = {} %}
            {% for k, v in item.items() %}
              {% set _ = trimmed_dict.update({k|trim: v|trim}) %}
            {% endfor %}
            {% set _ = processed_list.append(trimmed_dict) %}
          {% endfor %}
          {{ processed_list }}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 21:15:19