如何在Expect脚本中通过SSH自动传递CVS密码?
解决远程CVS自动输入密码的Expect脚本方案
刚好我之前也碰到过类似的场景——SSH免密已经搞定,但远程脚本里触发的CVS更新需要手动输密码,用Expect完全能解决!给你整理了两种可行的方案,你可以根据自己的需求选择:
方案1:独立Expect脚本
创建一个名为auto_cvs_update.exp的脚本,内容如下:
#!/usr/bin/expect -f # 从环境变量读取CVS密码,避免硬编码 set cvs_password $env(CVS_REMOTE_PASSWORD) # 启动SSH连接(这里的`name`是你的SSH别名) spawn ssh name # 跳过MOTD,等待远程服务器的命令提示符 expect { # 匹配常见的命令提示符($ 或 #,根据你的服务器实际情况调整) -re {\$|#} { # 发送运行远程脚本的命令 send "run_remote_script.sh\r" } } # 等待CVS弹出的密码输入提示 expect "Password:" # 发送密码并回车 send "$cvs_password\r" # 等待脚本执行完成,直到再次出现命令提示符 expect -re {\$|#} # 退出SSH连接 send "exit\r" expect eof
使用步骤:
- 给脚本添加执行权限:
chmod +x auto_cvs_update.exp - 设置环境变量(不要硬编码密码!):
export CVS_REMOTE_PASSWORD="你的CVS远程密码" - 运行脚本:
./auto_cvs_update.exp
方案2:嵌入到Bash脚本中
如果不想单独写Expect脚本,也可以把逻辑直接嵌入到Bash脚本里:
#!/bin/bash # 先设置CVS密码的环境变量(建议从安全的地方读取,比如密钥管理工具) export CVS_REMOTE_PASSWORD="你的CVS远程密码" # 调用Expect处理交互逻辑 expect << EOF spawn ssh name # 等待命令提示符,跳过MOTD expect -re {\$|#} send "run_remote_script.sh\r" # 匹配CVS的密码提示 expect "Password:" # 发送环境变量里的密码 send "\$env(CVS_REMOTE_PASSWORD)\r" # 等待脚本执行完毕 expect -re {\$|#} send "exit\r" expect eof EOF
关键注意事项:
- 命令提示符匹配:如果你的远程服务器提示符不是
$或#(比如是user@server:~$),需要调整正则表达式,比如改成-re {user@server:~\\$}(注意转义特殊字符) - 精准匹配密码提示:如果MOTD里意外出现类似
Password:的字符串,可以把匹配规则改成更精准的,比如CVS的提示通常是cvs update: password for xxx:,那可以写成expect "cvs update: password:" - 安装Expect:如果服务器上没装Expect,先安装:
- Debian/Ubuntu:
sudo apt install expect - RHEL/CentOS:
sudo yum install expect
- Debian/Ubuntu:
内容的提问来源于stack exchange,提问作者Pierre-Antoine Guillaume
相关产品推荐
相关产品推荐

