如何使用Ansible async模块实时捕获Shell命令输出?
解决方案:Ansible实时获取异步任务运行时输出
你之前的Playbook报错是因为单个Ansible任务只能使用一个模块,不能在同一个任务里同时调用async_status和shell模块。要实现实时读取异步任务的输出,需要把日志读取和任务状态检查拆分为独立任务,放在循环中执行。
正确的Playbook示例
- hosts: localhost tasks: - name: 启动持续输出的异步任务 shell: while true; do echo "test $(date)" >> ~/test; sleep 2; done async: 60 # 任务最长运行60秒 poll: 0 # 立即返回,不等待任务完成 register: cmd_result - name: 循环读取日志并检查任务状态 block: - name: 读取日志文件并清空内容 shell: cat ~/test && truncate -s 0 ~/test register: log_content changed_when: false # 避免标记为"changed"状态 - name: 打印最新日志内容(非空时) debug: msg: "{{ log_content.stdout_lines }}" when: log_content.stdout != "" - name: 检查异步任务是否完成 async_status: jid: "{{ cmd_result.ansible_job_id }}" register: job_status until: job_status.finished # 直到任务完成才停止循环 retries: 30 # 最多循环30次 delay: 5 # 每次循环间隔5秒
关键说明
- 异步任务启动:用
async: 60和poll:0启动后台任务,立即返回任务ID并注册到cmd_result。 - 循环逻辑:通过
block把日志读取、打印、状态检查三个任务打包,配合until实现循环执行,直到异步任务完成。 - 日志处理:每次循环读取日志后立即清空,避免重复打印旧内容;通过
changed_when: false让日志读取任务不触发状态变更。 - 状态检查:
async_status模块用来查询异步任务的运行状态,当job_status.finished为true时,循环终止。
内容的提问来源于stack exchange,提问作者Theo Cerutti
相关产品推荐
相关产品推荐

