Bash脚本中Expect模块密码验证超时返回0状态码的问题求助
问题分析与解决办法
你的脚本问题出在没有处理密码错误时的异常场景,而且Expect默认的超时行为没被正确捕获,导致即使超时也返回状态码0。
当密码错误时,SFTP服务器通常会再次输出password:提示符,或者直接返回Permission denied类的错误信息,但你的脚本只等待sftp>这一种情况,超时后Expect默认不会主动返回非零状态码,最终让外层Bash判断误以为连接成功。
修复后的脚本
function test_sftp_connection() { expect << EOF log_user 0 # 设置超时时间,避免无限等待(单位:秒) set timeout 10 spawn -noecho sftp -P $SFTP_SERVER_PORTNUMBER $SFTP_SERVER_USERNAME@$SFTP_SERVER_HOSTNAME # 等待密码提示 expect "password:" send "$SFTP_SERVER_PASSWORD\r" # 同时匹配成功、密码错误、认证失败、超时四种场景 expect { "sftp>" { # 连接成功,退出SFTP send "exit\r" exit 0 } "password:" { # 再次要求输入密码,说明密码错误 exit 1 } "Permission denied" { # 直接返回认证失败 exit 1 } timeout { # 超时场景,标记为失败 exit 1 } } EOF # 检查Expect脚本的退出状态 if [ $? -ne 0 ]; then echo "Unable to connect to the SFTP server." exit 1 fi }
关键修改点说明
- 设置超时时间:通过
set timeout 10明确超时时间,避免脚本无限挂起,超时后触发timeout分支返回非零状态。 - 多模式匹配:使用
expect { ... }语法同时监听多种场景,覆盖成功、密码错误、认证失败、超时所有情况,每个异常分支都主动exit 1,确保Expect脚本返回非零状态。 - 主动控制退出状态:在成功分支明确
exit 0,异常分支exit 1,让外层Bash能准确判断连接结果。
内容的提问来源于stack exchange,提问作者MaestroMaus
相关产品推荐
相关产品推荐

