Ansible expect模块日志写入失败及连接异常关闭问题求助
问题1:Ansible expect模块无法生成日志文件
解决思路
方案1:使用expect模块内置的logfile参数
expect模块原生支持logfile参数,可直接将命令的完整交互过程(包括输入输出)写入指定文件,同时保留输出到Ansible的STDOUT。修改Playbook如下:
- name: Register xyz agent and post install ansible.builtin.expect: command: "/path/to/myscript.sh" responses: (.*)Enterprise Manager Login(.*): "{{ oem_sys_pass }}" (.*)Agent Registration(.*): "{{ oem_agent_pass }}" timeout: 10000 logfile: "/path/to/mylogs.log"
方案2:启用shell解析管道命令
如果坚持使用tee,需要添加shell: yes参数——expect模块默认直接执行命令,不解析管道等shell元字符,开启该参数后会通过系统shell执行命令,管道即可正常生效:
- name: Register xyz agent and post install ansible.builtin.expect: command: "/path/to/myscript.sh | /usr/bin/tee /path/to/mylogs.log" responses: (.*)Enterprise Manager Login(.*): "{{ oem_sys_pass }}" (.*)Agent Registration(.*): "{{ oem_agent_pass }}" timeout: 10000 shell: yes
问题2:脚本执行中出现SSH连接关闭错误
解决思路
1. 配置SSH存活包避免连接超时
在Ansible配置文件(ansible.cfg)的[ssh_connection]段添加参数,让SSH客户端定时发送存活包,防止服务器主动断开连接:
[ssh_connection] ssh_args = -o ServerAliveInterval=60 -o ServerAliveCountMax=10
也可在Playbook中通过变量临时设置:
- name: Register xyz agent and post install ansible.builtin.expect: command: "/path/to/myscript.sh" responses: (.*)Enterprise Manager Login(.*): "{{ oem_sys_pass }}" (.*)Agent Registration(.*): "{{ oem_agent_pass }}" timeout: 10000 vars: ansible_ssh_common_args: "-o ServerAliveInterval=60 -o ServerAliveCountMax=10"
2. 调整目标服务器的sshd配置
修改目标服务器的/etc/ssh/sshd_config,开启客户端存活检测:
ClientAliveInterval 60 ClientAliveCountMax 10
修改后重启sshd服务:
systemctl restart sshd
3. 禁用命令输出缓冲
如果脚本运行时输出缓冲导致SSH通道长时间无数据传输,可使用unbuffer命令强制实时输出,避免连接被断开:
- name: Register xyz agent and post install ansible.builtin.expect: command: "/usr/bin/unbuffer /path/to/myscript.sh" responses: (.*)Enterprise Manager Login(.*): "{{ oem_sys_pass }}" (.*)Agent Registration(.*): "{{ oem_agent_pass }}" timeout: 10000 logfile: "/path/to/mylogs.log"
4. 启用异步执行
对于超长时间运行的任务,可使用Ansible异步执行特性,避免因SSH连接超时失败:
- name: Register xyz agent and post install ansible.builtin.expect: command: "/path/to/myscript.sh" responses: (.*)Enterprise Manager Login(.*): "{{ oem_sys_pass }}" (.*)Agent Registration(.*): "{{ oem_agent_pass }}" timeout: 10000 logfile: "/path/to/mylogs.log" async: 10000 poll: 60
async设置任务最大运行时长(秒),poll设置每隔多少秒轮询一次任务状态。
内容的提问来源于stack exchange,提问作者Surendra Anne
相关产品推荐
相关产品推荐

