Ansible执行Playbook时hosts节点重复输出问题求解
我来帮你拆解下这个问题——你看到tasks数组里有两个hosts节点,本质是因为每个任务(shell和debug)都会在JSON输出里生成独立的task条目,每个条目下都包含hosts节点。毕竟你配置了stdout_callback=json,Ansible会把每个任务的执行结果完整输出,所以shell任务的结果是一个task条目,debug任务的结果又是另一个,自然就出现了两个hosts节点。
下面给你几个贴合需求的解决思路,你可以根据实际场景选择:
思路1:移除debug模块,直接提取shell任务的结果
如果你只是想获取shell模块的stdout_lines,其实完全不需要debug模块。你可以直接运行playbook后,用工具(比如jq)过滤JSON输出,精准提取你需要的内容。
假设你的playbook是这样的:
- name: Run shell command hosts: your_target_hosts tasks: - name: Execute target shell command shell: "your_command_here" register: shell_result
运行playbook后,用jq过滤输出:
ansible-playbook your_playbook.yml | jq '.tasks[] | select(.task == "Execute target shell command") | .hosts[] .stdout_lines'
这样就能直接拿到shell任务的stdout_lines,不会有debug任务的冗余输出。
思路2:保留debug模块,优化输出并针对性提取
如果必须用debug模块来输出内容,你可以让debug只输出stdout_lines而不是整个注册变量,这样debug任务的JSON结果会更简洁。即使还是有两个tasks条目,你也可以精准过滤debug的结果。
修改playbook的debug任务:
- name: Print stdout_lines result debug: msg: "{{ shell_result.stdout_lines }}"
然后用jq提取debug任务的输出:
ansible-playbook your_playbook.yml | jq '.tasks[] | select(.task == "Print stdout_lines result") | .hosts[] .msg'
思路3:调整配置或自定义回调(适配2.5.x版本)
Ansible 2.5.x的json回调插件确实会输出所有任务的完整结果,如果你想全局控制输出,可以考虑:
- 临时修改
stdout_callback为minimal或yaml,但这样就不再是JSON格式; - 编写简单的自定义回调插件,只输出你关心的任务结果。不过自定义回调需要基础的Python能力,你可以参考Ansible官方文档的回调插件编写规范,过滤掉不需要的任务输出。
另外提一句:Ansible 2.5.x已经是停止维护的老旧版本了,如果条件允许,升级到2.9+或更高版本会有更合理的回调输出结构,以及更多的过滤选项哦。
内容的提问来源于stack exchange,提问作者sanjog panda

