如何将Ansible的output.stdout_lines传入Python文件并保留原格式输出
解决Ansible传递
stdout_lines到本地Python脚本的格式问题 你遇到的核心问题是Ansible直接传递列表类型的stdout_lines时,会被拆分成零散的命令行参数,导致Python通过sys.argv拿到的不是完整的数组结构,空行还会被Shell忽略,自然没法还原原格式和正常遍历。下面是具体的解决步骤:
1. 修改Ansible Playbook:将列表序列化为JSON字符串传递
把stdout_lines用Ansible的to_json过滤器转换成JSON字符串,并用单引号包裹,避免Shell解析JSON中的特殊字符。修改后的Playbook任务如下:
- name: Fetch routing info hosts: Windows tasks: - win_command: route print register: output - debug: msg={{ output.stdout_lines }} - command: python rInfoPython.py '{{ output.stdout_lines | to_json }}' delegate_to: localhost
2. 修改Python脚本:解析JSON字符串还原列表
现在Python脚本接收到的是一个完整的JSON数组字符串,我们可以用json模块解析成原有的列表结构,之后就能正常遍历和按原格式输出了:
import sys import json def main(): # 检查是否接收到数据 if len(sys.argv) < 2: print("Error: No routing data received") return # 解析JSON字符串为Python列表 try: routing_lines = json.loads(sys.argv[1]) except json.JSONDecodeError as e: print(f"Error parsing JSON: {e}") return # 按原格式输出所有行(包括空行) print("--- 原格式输出 ---") for line in routing_lines: print(line) # 示例:遍历并处理非空行 print("\n--- 处理后的非空行 ---") for line in routing_lines: stripped_line = line.strip() if stripped_line: print(stripped_line) if __name__ == "__main__": main()
为什么原来的方法不行?
当你直接传递{{ output.stdout_lines }}时,Ansible会把列表中的每个元素都作为独立的命令行参数传给Python脚本。比如原列表中的空字符串会被Shell忽略,其他元素会被拆分成sys.argv[1]、sys.argv[2]...这样的零散值,你拿到的是一堆碎片化的字符串,而不是完整的列表结构,自然无法还原原格式和正确遍历。
通过JSON序列化后,整个列表变成了一个单一的字符串参数,Python可以完整解析出原有的列表结构,包括空行和所有元素的顺序。
内容的提问来源于stack exchange,提问作者R M
相关产品推荐
相关产品推荐

