You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible调用expect执行AD域加入脚本时RPM安装异常中断问题

故障根因

故障完全是expect配置错误导致的,核心问题有4个:

  • 超时时间设置过短:你写的set timeout 10代表expect只要10秒没收到脚本的任何输出,就会直接终止spawn拉起的进程。yum安装RPM包过程中,大包解压、依赖校验、事务提交阶段经常会出现十几秒到几十秒不等的无输出窗口,这就是为什么安装会无规律卡在17、42、46个包的位置——卡在哪完全取决于当时哪个安装步骤的无输出时长超过了10秒阈值。
  • 执行逻辑错误:你直接把expect语法写在了ansible.builtin.shell模块的执行块里,但shell模块默认调用bash解释器,根本识别不了spawn、expect这些expect专属语法,相当于你写的expect逻辑根本没按预期跑。
  • 匹配逻辑冗余且脆弱:你加的3段expect -exact "\r"完全没有必要,输入回车后脚本不会单独返回一个\r字符供你匹配;同时用-exact做精确匹配容错性极差,只要提示语前后多一个空格、换行或者终端控制字符就会匹配失败。
  • 缺少伪终端配置:sudo默认要求执行环境提供tty,你没给spawn的进程分配伪终端,也可能导致输出截断、进程异常挂死。
修正方案

直接替换成下面的Ansible任务配置即可,已经把上述问题全部修复:

- name: Joining of system to the domain
  ansible.builtin.shell: |
    /usr/bin/expect << 'EOF'
    # 超时设置为300秒(5分钟),足够覆盖全量RPM安装流程,安装速度慢的环境可以改成-1表示永不超时
    set timeout 300
    # 分配伪终端,适配sudo的tty校验要求
    spawn -pty sudo ./addto-AD
    match_max 100000

    # 匹配位置输入提示,加超时、提前退出的异常捕获
    expect {
        "*Please Enter the Environment*" { send -- "Seattle\r" }
        timeout { puts "ERR: 等待位置输入提示超时"; exit 1 }
        eof { puts "ERR: 脚本在输入位置前异常退出"; exit 1 }
    }

    # 匹配提权用户名输入提示
    expect {
        "*Enter Elevated AD Username*" { send -- "{{ elevated }}\r" }
        timeout { puts "ERR: 等待用户名输入提示超时"; exit 1 }
        eof { puts "ERR: 脚本在输入用户名前异常退出"; exit 1 }
    }

    # 匹配密码输入提示
    expect {
        "*Enter Password for User*" { send -- "{{ elevated_pass }}\r" }
        timeout { puts "ERR: 等待密码输入提示超时"; exit 1 }
        eof { puts "ERR: 脚本在输入密码前异常退出"; exit 1 }
    }

    # 等待脚本执行完成,透传脚本的退出码给Ansible
    expect eof
    catch wait result
    set exit_code [lindex $result 3]
    exit $exit_code
    EOF
  args:
    # 替换成你addto-AD脚本实际存放的目录
    chdir: /your/script/path
  register: ad_join_res
  failed_when: ad_join_res.rc != 0
补充说明
  • 如果你的Ansible远程用户执行sudo时需要输入密码,需要在spawn -pty sudo ./addto-AD下面新增一段密码匹配逻辑,发送Ansible配置里的sudo密码即可。
  • 提示语匹配用*关键词*的通配模式替换原来的精确匹配,能兼容提示语前后的不可见控制字符、空格、换行,不会因为微小的输出格式差异导致匹配失败。
  • 手动执行脚本正常、Ansible调度异常的核心差异就是:手动操作时你会一直等脚本跑完,不会因为暂时没输出就杀进程;expect默认的超时机制会在无输出时主动终止进程,刚好命中了yum安装时的无输出窗口。

内容的提问来源于stack exchange,提问作者HBach

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 10:48:15