Ansible如何通过本地脚本解析JSON格式的变量
解决Ansible传递JSON变量给本地Python脚本的问题
我帮你分析下这个问题——你遇到的核心是直接在shell命令里嵌入JSON变量时,JSON里的引号、特殊字符被shell解析转义,导致脚本拿不到完整的有效JSON。这里有几个靠谱的解决办法:
方案1:先把JSON写入本地临时文件(最稳妥易调试)
这种方式绕开了shell转义的坑,步骤清晰还方便排查问题:
- name: 将VPN日志JSON写入本地临时文件 copy: content: "{{ result_VPN_log_json | to_nice_json }}" dest: "/tmp/vpn_log.json" delegate_to: localhost - name: 调用本地脚本解析JSON文件 shell: "./checkit.py /tmp/vpn_log.json" delegate_to: localhost register: parse_result - name: 查看解析结果 debug: var: parse_result.stdout
记得修改你的checkit.py,让它支持接收文件路径参数并读取JSON内容,比如脚本里用open(sys.argv[1])来加载文件,这样比管道传递更稳定。
方案2:用Ansible的stdin直接传递(无需临时文件)
如果不想生成临时文件,Ansible 2.10及以上版本支持通过stdin参数直接传递内容,完全避开shell解析:
- name: 通过stdin传递JSON给本地脚本 command: "./checkit.py" delegate_to: localhost args: stdin: "{{ result_VPN_log_json | to_json }}" register: parse_result
对应的checkit.py需要从标准输入读取内容,示例代码如下:
import sys import json def main(): # 从标准输入读取JSON json_data = json.load(sys.stdin) # 这里写你的解析逻辑,比如提取特定日志并输出 # ... if __name__ == "__main__": main()
为什么原来的写法会失败?
你之前用shell echo '{{ result_VPN_log_json }}' | ./checkit.py时,JSON里的双引号会被shell当成命令的边界符号,导致实际传递给脚本的是被截断或转义后的残缺JSON。比如JSON里的"status": "success",shell会把中间的双引号当成echo命令的结束标记,最后传给脚本的内容完全不是你想要的完整JSON结构。
另外,建议始终用to_json过滤器确保变量被正确序列化为标准JSON字符串,避免Ansible模板渲染时出现格式问题。
内容的提问来源于stack exchange,提问作者Piotr
相关产品推荐
相关产品推荐

