Expect脚本SSH远程Git拉取代码报错问题排查请求
你的Expect脚本问题排查与修复方案
首先一眼就能看到核心问题:你远程执行的SSH命令只做了cd path/to/dir,根本没加git pull origin master,所以SSH连上服务器后啥拉取操作都没触发,这肯定会出问题啊。除此之外,还有几个Expect脚本的常见坑需要调整:
1. 先把远程命令链补全
你得把cd和git pull放到同一个远程命令里,用&&连接(确保目录切换成功才执行拉取),修改后的spawn命令应该是:
spawn ssh -t user@host.domain 'cd path/to/dir && git pull origin master'
如果用分号;的话,就算cd失败,git pull还是会执行,容易报错,所以&&更稳妥。
2. 优化匹配规则,别死磕固定字符串
你的脚本里硬匹配"continue"、"assword:",但实际环境中提示可能有变体——比如首次SSH连接的完整提示是Are you sure you want to continue connecting (yes/no)?,git的用户名提示可能是Username for 'https://github.com':,大小写也可能有差异。用正则匹配能兼容这些情况:
- 匹配SSH首次连接确认:
expect -re "Are you sure you want to continue connecting.*" - 匹配密码提示:
expect -re "(Password|password):" - 匹配git用户名提示:
expect -re "(Username|username):"
这样就不会因为提示字符串的细微差异导致脚本卡壳了。
3. 删掉多余的sleep
Expect是基于事件触发的,sleep完全是画蛇添足——不仅会增加不必要的延迟,还可能错过匹配时机。除非是极端特殊场景,否则直接把所有sleep 1都删掉。
4. 修复后的完整脚本
#!/usr/bin/expect -f # 可选:打开调试模式,排查问题时可以取消注释 # exp_internal 1 # 执行远程命令:切换目录并拉取master分支 spawn ssh -t user@host.domain 'cd path/to/dir && git pull origin master' # 处理SSH连接的主机密钥确认和登录密码 expect { -re "Are you sure you want to continue connecting.*" { send "yes\r" exp_continue # 继续匹配后续的密码提示 } -re "(Password|password):" { send "你的SSH密码\r" } } # 处理git拉取时的用户名/密码认证 expect { -re "(Username|username):" { send "你的Git用户名\r" exp_continue } -re "(Password|password):" { send "你的Git密码\r" } } # 等待命令执行完成,结束会话 expect eof # 如果需要保持交互看结果,可以换成interact,但自动化部署一般用expect eof
额外小贴士
- 强烈建议给服务器和Git仓库配置SSH密钥免密,这样脚本里就不用明文写密码了,安全性和可靠性都能提升一大截。
- 可以加个日志记录,比如在脚本开头加
log_file /var/log/deploy_pull.log,方便后续排查问题。
内容的提问来源于stack exchange,提问作者Dawid Zbiński
相关产品推荐
相关产品推荐

