Expect脚本批量修改默认密码失败问题求助
排查Expect脚本批量改密码失效的问题
常见问题点及修复方案
1. 漏了密码确认步骤
绝大多数Linux系统改密码时,都会要求两次输入新密码——先输New password,再输Retype new password。如果你的脚本只处理了第一次输入,流程会直接中断,系统根本不会保存新密码。
给你个修改后的脚本示例:
#!/usr/bin/expect -f set timeout 30 set host [lindex $argv 0] set old_pass [lindex $argv 1] set new_pass [lindex $argv 2] spawn ssh root@$host expect "password:" send "$old_pass\r" # 匹配首次改密提示 expect "New password:" send "$new_pass\r" # 新增:处理确认密码的提示 expect "Retype new password:" send "$new_pass\r" # 等改密成功的提示,确保操作完成 expect "passwd: all authentication tokens updated successfully." expect eof
2. 匹配的字符串不对(含隐藏字符)
有些系统的New password提示可能带终端颜色、换行符或者空格,看起来和你写的字符串一样,但实际Expect匹配的是精确字符,差一点都不行。
解决办法:
- 用模糊匹配,比如正则:
expect -re "New password.*:" - 开debug模式(
expect -d 你的脚本.exp)查看实际收到的字符,比如日志里如果显示New password: \r,那你就得匹配"New password: \r"或者用正则忽略换行。
3. 脚本提前退出,没等操作完成
如果脚本发完密码就直接退出,SSH连接会断开,系统还没来得及把新密码写入,自然改密失败。
解决办法:
- 一定要等系统返回改密成功的提示再结束,比如加个明确的匹配:
expect { "passwd: all authentication tokens updated successfully." { puts "$host 密码修改成功" } timeout { puts "$host 改密超时,可能失败" exit 1 } } expect eof
4. 终端环境变量的问题
有些系统首次登录强制改密时,对终端类型有要求。可以在spawn SSH的时候指定TERM变量:
spawn ssh -o "TERM=xterm" root@$host
验证技巧
- 手动改一次密码,把所有提示的精确内容记下来(包括标点、空格、换行),确保脚本里的
expect字符串和实际完全一致。 - 用
expect -d运行脚本,查看debug日志:- 确认
New password确实被匹配到(日志会显示expect: does "...New password..." match pattern "New password:"? yes) - 确认两次密码都发出去了,并且系统返回了成功提示。
- 确认
内容的提问来源于stack exchange,提问作者jersey bean
相关产品推荐
相关产品推荐

