如何通过Bash脚本实现SSH登录服务器、带密码su及跳转至另一服务器
这个问题我太熟了——交互式的密码输入一直是bash脚本自动化的痛点,毕竟bash本身没法自动响应这种需要人工输入的交互场景。最稳妥的解决办法是用expect工具,它专门就是用来搞定这类交互式命令的。
解决方法:用
expect实现全流程自动化 expect是一款专门处理交互式程序的工具,完美适配你需要自动输入su密码的场景。下面是具体的实现步骤和两种方案:
1. 先安装expect
大部分Linux发行版默认没有预装,先在你的本地机器或者server1上完成安装:
# Debian/Ubuntu 系列系统 sudo apt install expect # RHEL/CentOS 系列系统 sudo yum install expect
2. 编写自动化脚本
你可以选择单独写一个expect脚本,或者把expect逻辑嵌入bash脚本里,两种方案都给你列出来:
方案一:独立的expect脚本
创建一个名为auto_switch_ssh.exp的文件,内容如下:
#!/usr/bin/expect # 从命令行参数获取配置信息 set server1_addr [lindex $argv 0] set target_su_user [lindex $argv 1] set su_pwd [lindex $argv 2] set server2_addr [lindex $argv 3] # 第一步:SSH登录server1 spawn ssh $server1_addr # 第二步:执行su切换用户,自动输入密码 expect "$ " # 注意:这里要匹配server1的实际命令提示符,比如如果是`user@server1:~$`就改成这个 send "su $target_su_user\r" expect "Password:" send "$su_pwd\r" # 第三步:切换用户成功后,SSH登录server2 expect "$ " # 这里要匹配切换用户后的命令提示符 send "ssh $server2_addr\r" # 保持交互状态,避免执行完直接退出 interact
给脚本添加执行权限:
chmod +x auto_switch_ssh.exp
运行方式(替换成你的实际参数):
./auto_switch_ssh.exp server1.example.com user1 your_su_password server2.example.com
方案二:嵌入bash脚本的混合写法
如果你想把所有逻辑放在一个bash脚本里,可以这样写:
#!/bin/bash # 先定义好你的配置信息 SERVER1="server1.example.com" TARGET_USER="user1" SU_PASSWORD="your_su_password" SERVER2="server2.example.com" # 嵌入expect逻辑 expect << EOF spawn ssh $SERVER1 expect "$ " send "su $TARGET_USER\r" expect "Password:" send "$SU_PASSWORD\r" expect "$ " send "ssh $SERVER2\r" interact EOF
添加执行权限后直接运行即可。
3. 关键注意事项
- 提示符匹配要准确:脚本里的
expect "$ "必须和你实际的命令提示符完全匹配,比如server1的提示符是root@server1:~#,就一定要改成对应的字符串,不然expect会找不到匹配项导致脚本卡壳。 - 安全第一!:明文写密码在脚本里风险极高,建议用环境变量传递密码:
或者从加密文件中读取密码,彻底避免明文暴露。# 运行前先设置环境变量 export SU_PASSWORD="your_secure_password" # 脚本里用$env(SU_PASSWORD)获取 send "$env(SU_PASSWORD)\r" - 更安全的替代方案:如果有权限调整配置,尽量避免用密码su:比如给当前用户配置免密sudo权限,或者给server1上的目标用户配置SSH免密登录server2,这样流程会更简洁安全:
# 配置免密sudo后,一行命令就能搞定 ssh server1 "sudo -u user1 ssh server2"
内容的提问来源于stack exchange,提问作者Coder94
相关产品推荐
相关产品推荐

