在Ansible自动化运维场景中,经常会遇到需要执行耗时较长的脚本任务,比如数据备份、批量数据处理等,这类任务如果采用默认的同步执行方式,会导致Ansible控制节点长时间等待,甚至触发超时错误。同时用户还需要实时查看脚本的运行日志,确认执行进度和状态,因此需要掌握后台运行脚本与实时日志观察的正确方法。

后台长期运行脚本的实现方式
Ansible提供了异步执行任务的能力,可以让任务在远程节点后台运行,控制节点无需一直等待任务完成,这是实现长期运行脚本的基础。
异步任务核心参数
在Ansible的shell或者command模块中,通过以下参数配置异步执行:
- async:设置任务的最大运行时间,单位为秒,超过这个时间任务会被终止,设置为0表示不限制运行时间。
- poll:设置轮询任务状态的间隔时间,单位为秒,设置为0表示任务直接后台运行,不主动轮询状态。
基础后台运行示例
以下是一个让脚本在远程节点后台运行的简单示例,脚本会持续运行并输出日志到指定文件:
---
- name: 后台运行长期脚本示例
hosts: all
tasks:
- name: 启动后台脚本任务
shell: /opt/long_running_script.sh >> /var/log/long_script.log 2>&1 &
async: 0 # 不限制脚本运行时间
poll: 0 # 不轮询状态,直接后台运行
register: script_result
- name: 输出任务启动状态
debug:
msg: "后台脚本已启动,任务ID: {{ script_result.ansible_job_id }}"
上述示例中,脚本的输出被重定向到/var/log/long_script.log文件,同时脚本进程在后台运行,Ansible任务执行后立即返回,不会等待脚本结束。
更可靠的异步任务管理方式
如果需要后续确认后台任务的状态,或者需要等待任务完成再执行后续操作,可以使用async_status模块配合轮询:
---
- name: 可控的后台脚本执行示例
hosts: all
tasks:
- name: 启动后台脚本
shell: /opt/long_running_script.sh >> /var/log/long_script.log 2>&1
async: 3600 # 最长运行1小时
poll: 0
register: async_job
- name: 轮询检查任务状态
async_status:
jid: "{{ async_job.ansible_job_id }}"
register: job_status
until: job_status.finished # 直到任务完成
retries: 60 # 最多轮询60次
delay: 60 # 每次轮询间隔60秒
- name: 输出最终执行结果
debug:
msg: "脚本执行完成,状态: {{ job_status }}"
实时日志观察的实现方法
脚本在后台运行后,日志输出到指定文件,我们可以通过多种方式实现实时观察日志的效果。
通过Ansible执行实时查看命令
如果只是临时需要查看日志,可以在Ansible中执行tail -f命令,不过需要注意这种方式会阻塞当前任务,直到手动中断:
---
- name: 实时查看脚本日志
hosts: all
tasks:
- name: 执行tail -f查看日志
shell: tail -f /var/log/long_script.log
register: log_output
ignore_errors: true # 允许手动中断时忽略错误
- name: 输出日志内容
debug:
msg: "{{ log_output.stdout_lines }}"
这种方式适合临时调试场景,不适合自动化流程中使用,因为会阻塞Ansible执行流程。
结合远程节点的日志服务
更推荐的方式是将脚本日志接入远程节点的系统日志服务,比如rsyslog,然后通过集中日志平台或者远程节点的日志查看工具实时观察:
首先修改脚本的日志输出方式,将日志发送到syslog:
#!/bin/bash
# 长期运行脚本示例,输出日志到syslog
while true; do
logger -t long_running_script "当前执行进度: $(date)"
sleep 10
done
然后在Ansible中配置rsyslog,确保日志可以被正常收集,之后可以通过journalctl -f -t long_running_script命令实时查看该脚本的日志:
---
- name: 配置实时日志观察环境
hosts: all
tasks:
- name: 查看脚本实时日志
shell: journalctl -f -t long_running_script
register: realtime_log
ignore_errors: true
- name: 输出实时日志
debug:
msg: "{{ realtime_log.stdout_lines }}"
通过文件监听实现日志实时获取
如果日志是输出到普通文件,也可以在Ansible中通过循环读取文件新增内容的方式实现近似实时观察:
---
- name: 循环读取日志文件新增内容
hosts: all
tasks:
- name: 持续读取日志文件
shell: tail -n 10 /var/log/long_script.log # 每次读取最后10行
register: log_content
until: false # 永远不结束,直到手动中断
retries: 9999
delay: 5 # 每5秒读取一次
- name: 输出日志内容
debug:
msg: "{{ log_content.stdout_lines }}"
注意事项
- 后台运行的脚本需要确保不会因为Ansible任务结束而被终止,建议脚本内部做好进程守护,或者使用
nohup命令配合执行。 - 日志文件路径需要确保远程节点有写入权限,避免日志输出失败。
- 如果后台任务不需要后续跟踪状态,建议设置
poll: 0和async: 0,减少Ansible控制节点的资源占用。 - 实时查看日志的任务如果不需要阻塞流程,可以单独作为一个Ansible任务在另一个终端执行,避免影响主流程的运行。
实际使用中需要根据具体的脚本类型和运维需求,选择合适的后台运行和日志观察方式,平衡自动化效率和可观测性。
Ansible后台运行脚本实时日志观察ansible_playbook修改时间:2026-07-14 11:54:31