Ansible执行Python脚本后JSON转Python格式问题及优化咨询
Ansible中保留JSON原始格式并构建汇总JSON的问题解答
为什么JSON串会被转为Python格式?
这是Ansible的默认行为导致的:当你用shell模块执行命令并注册结果时,Ansible会自动检测命令输出是否是有效的JSON。如果是,它会把这个JSON字符串解析成Python原生的数据结构(比如列表、字典),存放在stdout字段里。当你在模板中直接引用这个字段时,输出的是Python对象的字符串表示,自然就会出现[u'3'](Python2的Unicode字符串)、True(Python布尔值)这类和标准JSON不一致的格式。
而你第二个debug任务能拿到标准JSON串,是因为你只是直接输出了单个stdout的字段值,没有进行复杂的结构拼接;但当你把它和其他内容组合成嵌套JSON结构时,Ansible会把解析后的Python对象转成字符串,就变成了Python语法格式。
如何保留原始JSON串?
有两种简单可靠的解决办法:
- 方法1:使用
stdout_raw字段(Ansible 2.5+版本支持):当Ansible自动解析JSON到stdout时,会把原始的JSON字符串保留在stdout_raw字段里。你只需要把模板里的cmd['stdout']改成cmd['stdout_raw'],就能拿到未被解析的原始JSON文本。 - 方法2:用
to_json过滤器转回标准JSON:如果已经使用了stdout对应的Python对象,直接用{{ cmd.stdout | to_json }}过滤器,就能把Python数据结构重新转换成符合标准的JSON字符串,自动处理True→true、u'3'→"3"这类格式差异。
更优的汇总JSON构建方式
手动用debug的msg拼接JSON字符串很容易出错(比如多余的逗号、引号不匹配),推荐用Ansible的set_fact来构建字典结构,再统一转成JSON,既整洁又可靠。
修改后的Playbook示例:
tasks: - name: Execute Python Script shell: "python /srv/sources/{{ item.script }}" async: 30000 poll: 10 ignore_errors: yes failed_when: false register: result loop: - { script: 'checks_lines.py', variable: 'checks_lines' } - { script: 'checks_permissions.py', variable: 'checks_permissions' } - name: Build summary dictionary set_fact: summary: >- {% set output = {} %} {% for host in ansible_play_hosts %} {% set host_data = {} %} {% for cmd in hostvars[host]['result']['results'] %} {% do host_data.update({cmd.item.variable: cmd.stdout}) %} {% endfor %} {% do output.update({host: host_data}) %} {% endfor %} {{ output }} run_once: true - name: Output summary as valid JSON debug: msg: "{{ summary | to_json }}" run_once: true
这个方法的优势:
- 利用Ansible的字典操作构建结构化数据,避免手动拼接字符串的语法错误
- 最后通过
to_json过滤器统一转换,确保输出的是标准JSON格式 - 结构清晰,后续维护和扩展更方便
内容的提问来源于stack exchange,提问作者david hautbois
相关产品推荐
相关产品推荐

