Ansible json_query解析JSON报expected token ','错误排查
问题原因
你遇到的报错核心是两个问题:
- 引号嵌套冲突:Jinja2模板解析时,你在单引号包裹的
json_query表达式内部,直接用了同类型的单引号包裹字符串memberWeight,导致模板引擎提前截断了查询语句,把memberWeight识别为非法语法节点,才抛出expected token ',', got 'memberWeight'错误。 - JMESPath查询语法错误:你写的两个查询逻辑不符合目标JSON结构:
- 第一个查询里
[].option['memberWeight']逻辑不成立,dc1-indb-tst1:3306对应的值是配置对象数组,不存在嵌套的option.memberWeight结构 - 第二个查询里
topology.[?option == 'memberWeight']路径错误,option字段是拓扑节点下主机对应数组的元素属性,不是topology的直接子节点
- 第一个查询里
正确写法
Ansible官方推荐将JMESPath查询语句单独定义为变量,彻底规避引号转义的坑,写法如下:
- name: 获取dc1-indb-tst1:3306节点的memberWeight值 ansible.builtin.debug: msg: "{{ clust_opts | community.general.json_query(jmespath_query) }}" vars: jmespath_query: "defaultReplicaSet.topology.\"dc1-indb-tst1:3306\"[?option == 'memberWeight'].value | [0]"
执行后会直接返回你预期的50。
查询逻辑说明
- 首先按路径定位到
defaultReplicaSet.topology下dc1-indb-tst1:3306对应的配置数组,带特殊字符(冒号、横杠)的键名需要用引号包裹,避免JMESPath把冒号识别成语法符号 - 用
[?option == 'memberWeight']过滤数组,筛选出option字段等于memberWeight的配置对象 - 用
.value提取匹配对象的value字段,此时返回的是单元素数组["50"] - 最后通过管道
| [0]取数组第一个元素,直接得到字符串格式的结果"50"
如果你不想单独定义变量,也可以通过转义引号直接写在过滤器参数里,注意内外引号类型不要重复:
- name: 获取dc1-indb-tst1:3306节点的memberWeight值 ansible.builtin.debug: msg: "{{ clust_opts | community.general.json_query(\"defaultReplicaSet.topology.'dc1-indb-tst1:3306'[?option=='memberWeight'].value | [0]\") }}"
内容的提问来源于stack exchange,提问作者bfowler
相关产品推荐
相关产品推荐

