在SSH中使用Expect远程安装pkg包时密码传递失败求助
解决SSH会话中使用Expect传递密码安装pkg文件的问题
我帮你分析一下脚本里的几个关键问题,这些正是导致密码传递失败的核心原因:
错误1:两个独立的spawn命令
你现在的脚本先spawn了SSH连接,但还没等成功登录远程机器,就直接在本地spawn了sudo installer命令——这个安装命令根本没在目标远程机器上运行,自然无法完成安装操作。正确的思路是把安装命令放到SSH会话内部,作为远程执行的指令。错误2:密码发送的格式错误
第二个send语句里写的是xxx/r,这里的回车符应该是\r(不是/r),错误的格式会导致系统无法识别你发送的密码。错误3:
exp_continue的误用
在SSH登录阶段,发送密码后使用exp_continue会让Expect持续等待下一个匹配,但你没有处理登录成功后的远程提示符,脚本会一直卡在这个阶段,无法执行后续的sudo命令。
修正后的脚本示例
#!/bin/bash agentpath="/Users/vigneshganapathy/Downloads/FS-Agent" pass="xxx" expect -c ' # 设置超时为无限,避免安装命令执行超时 set timeout -1 # 启动SSH连接 spawn ssh -o StrictHostKeyChecking=no shyamkarthikv@192.168.57.33 # 匹配SSH密码提示符并发送密码 expect "*?assword:" {send "'"$pass"'\r"} # 等待远程机器的提示符(这里假设是$,如果是#或其他标识请自行调整) expect "$ " # 在远程机器上发送sudo安装命令 send "sudo installer -pkg \"/tmp/FS-Agent/FS-Agent.pkg\" -target \"/\"\r" # 匹配sudo的密码提示符并发送密码 expect "*?assword:" {send "'"$pass"'\r"} # 等待安装命令执行完成,回到远程提示符 expect "$ " # 退出SSH会话 send "exit\r" expect eof '
关键优化点说明
- 用单引号包裹Expect脚本内容,避免Bash提前替换内部变量,同时通过
'"$pass"'的方式将Bash的密码变量安全传递给Expect。 - 增加
set timeout -1避免因安装命令执行时间过长导致超时退出。 - 登录后等待远程提示符确认登录成功,再执行后续命令,确保操作都在远程机器上进行。
- 明确处理SSH和sudo两个阶段的密码请求,最后主动退出SSH会话并等待连接结束。
内容的提问来源于stack exchange,提问作者Vignesh Gv
相关产品推荐
相关产品推荐

