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

Expect脚本if语句失效:批量修改400台服务器账号密码

我来帮你搞定这个Expect脚本的问题!你遇到的if语句报错,大概率是把Shell的条件判断语法硬套到Expect里了——毕竟这俩的语法差异真不小,Expect基于TCL,逻辑写法和Shell完全不一样。

先给你一个适配你场景的完整Expect脚本,能同时处理账号过期提示和普通bash提示符两种情况,而且不会有语法错误:

#!/usr/bin/expect -f

# 设置超时时间,根据你的网络情况调整,比如30秒足够大部分场景
set timeout 30

# 从命令行传参:服务器地址、用户名、旧密码、新密码
set server [lindex $argv 0]
set username [lindex $argv 1]
set old_pass [lindex $argv 2]
set new_pass [lindex $argv 3]

# 启动SSH连接
spawn ssh $username@$server

# 核心的多场景匹配逻辑
expect {
    # 匹配账号过期的提示(请根据你实际看到的提示调整正则,*是通配符)
    "You are required to change your password immediately*" {
        send "$old_pass\r"
        expect "New password:"
        send "$new_pass\r"
        expect "Retype new password:"
        send "$new_pass\r"
        expect eof
    }
    # 匹配普通bash提示符(支持$或#结尾的提示符,用正则匹配)
    -re {\$|#} {
        send "passwd\r"
        expect "Current password:"
        send "$old_pass\r"
        expect "New password:"
        send "$new_pass\r"
        expect "Retype new password:"
        send "$new_pass\r"
        send "exit\r"
        expect eof
    }
    # 处理初始SSH登录的密码提示(输完密码后继续匹配上面的两种场景)
    "Password:" {
        send "$old_pass\r"
        exp_continue
    }
}

重点说明(帮你避开之前的坑):

  • 不要用Shell的if语法写Expect:Expect里的条件判断如果要用if,格式是if { TCL风格的条件 } { 执行动作 },比如if { $var == "xxx" } { ... },而不是Shell的if [ $var = "xxx" ]——这也是你之前if报错的核心原因。
  • 用Expect的多模式匹配更高效:像上面脚本里的expect { ... }分支,直接匹配不同的提示文本,比硬写if判断更贴合Expect的设计逻辑,也不容易出错。
  • 正则匹配要精准:如果你的过期提示或者提示符和示例不一样,一定要调整引号里的内容,比如有些服务器的过期提示可能是Your password has expired.,那就把第一个匹配项改成这个。
  • 批量执行的注意事项:给400台服务器执行的话,建议加个Shell循环套这个Expect脚本,同时可以加日志记录每台服务器的执行结果,避免出问题找不到原因。

你可以先拿一两台服务器测试这个脚本,调整好匹配的提示文本后再批量执行~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:50:29