使用 expect
自动登陆脚本,可以自动输入密码。
1. 使用示例
~/.auto_login --help
错误: 参数不足
Auto SSH Login v1.0.1
用法: Auto SSH Login 用户名 跳板机地址 端口 跳板机密码 [开发机地址] [开发机密码] [命令]
参数说明:
用户名 - 跳板机用户名
跳板机地址 - 跳板机IP或域名
端口 - 跳板机SSH端口
跳板机密码 - 跳板机登录密码
开发机地址 - [可选] 开发机地址 (用户名@主机名)
开发机密码 - [可选] 开发机登录密码
命令 - [可选] 登录后要执行的命令
示例:
./auto_login user jumper.example.com 22 password
./auto_login user jumper.example.com 22 password dev@server.com devpassword
./auto_login user jumper.example.com 22 password dev@server.com "" "cd /home/work"
2. 自动登陆脚本 auto_login
#!/usr/bin/expect -f
# 设置标题和版本
set script_name "Auto SSH Login"
set version "1.0.1"
# 关闭expect的超时
set timeout -1
# 设置窗口自适应
trap {
set rows [stty rows]
set cols [stty columns]
stty rows $rows columns $cols < $spawn_out(slave,name)
} WINCH
# 显示帮助信息的函数
proc show_help {} {
global script_name version
puts "\n$script_name v$version"
puts "用法: $script_name 用户名 跳板机地址 端口 跳板机密码 \[开发机地址\] \[开发机密码\] \[命令\]"
puts "\n参数说明:"
puts " 用户名 - 跳板机用户名"
puts " 跳板机地址 - 跳板机IP或域名"
puts " 端口 - 跳板机SSH端口"
puts " 跳板机密码 - 跳板机登录密码"
puts " 开发机地址 - \[可选\] 开发机地址 (用户名@主机名)"
puts " 开发机密码 - \[可选\] 开发机登录密码"
puts " 命令 - \[可选\] 登录后要执行的命令\n"
puts "示例:"
puts " ./auto_login user jumper.example.com 22 password"
puts " ./auto_login user jumper.example.com 22 password dev@server.com devpassword"
puts " ./auto_login user jumper.example.com 22 password dev@server.com \"\" \"cd /home/work\"\n"
exit 0
}
# 参数检查
if {[llength $argv] < 4} {
puts "错误: 参数不足"
show_help
}
# 处理帮助参数
if {[lindex $argv 0] == "-h" || [lindex $argv 0] == "--help"} {
show_help
}
# 设置参数
set USER [lindex $argv 0]
set JUMPER_HOST [lindex $argv 1]
set JUMPER_PORT [lindex $argv 2]
set JUMPER_PASSWORD [lindex $argv 3]
set HOST [lindex $argv 4]
set PASSWORD [lindex $argv 5]
set CMD [lindex $argv 6]
# 日志输出函数
proc log_info {message} {
puts "\[INFO\] $message"
}
proc log_error {message} {
puts "\[ERROR\] $message"
}
# SSH到目标机器的函数
proc ssh_to_target {host password cmd} {
global JUMPER_HOST
# 确定SSH参数
set ssh_options "-o GSSAPIAuthentication=no"
# 根据目标主机特性选择SSH命令
if {[string first "172.17" "$host"] != -1} {
# 对特定IP段使用不同的SSH参数
set ssh_cmd "ssh $host"
} elseif {[string match "150.223.248*" "$JUMPER_HOST"] || \
[string match "cwai*" "$JUMPER_HOST"] || \
"$host" == "123" || \
"$host" == "127.0.0.1"} {
set ssh_cmd "ssh $ssh_options $host"
set password ""
} else {
set ssh_cmd "ssh $ssh_options $host"
}
# 发送SSH命令
send "$ssh_cmd\r"
log_info "连接到目标主机: $host"
# 如果提供了密码则处理密码提示
if {"$password" != ""} {
expect {
-re "password:" {
send "$password\r"
log_info "已发送目标主机密码"
}
timeout {
log_error "等待密码提示超时"
return 0
}
}
}
# 等待shell提示符并设置环境
expect {
-re {[#\$%>]} {
# 设置环境变量
send "export LANG=en_US.UTF-8; export LC_ALL=en_US.UTF-8; export LC_CTYPE=en_US.UTF-8\r"
# 等待命令执行完成
expect -re {[#\$%>]}
# 执行自定义命令
if {"$cmd" != ""} {
send "$cmd\r"
log_info "执行命令: $cmd"
}
}
eof {
log_error "连接到 $host 意外关闭"
exit 1
}
timeout {
log_error "等待 $host 提示符超时"
exit 1
}
}
return 1
}
# 主程序
log_info "正在连接跳板机: $USER@$JUMPER_HOST:$JUMPER_PORT"
spawn ssh $USER@$JUMPER_HOST -p $JUMPER_PORT
expect {
-re "Are you sure you want to continue connecting.*" {
send "yes\r"
log_info "已确认主机指纹"
exp_continue
}
-re "password:" {
send "$JUMPER_PASSWORD\r"
log_info "已发送跳板机密码"
exp_continue
}
eof {
log_error "SSH连接意外关闭"
exit 1
}
timeout {
log_error "SSH连接超时"
exit 1
}
-re "@.*(\\\$|#|%|>)" {
if {"$HOST" != ""} {
ssh_to_target $HOST $PASSWORD $CMD
}
}
}
interact
exit
#------------------------------
# 使用示例
#alias autologin='expect $HOME/.auto_login'
#alias dev1='autologin root@host 22 password'
#alias dev2='autologin root@host 22 password work@host password "cd /home/work && clear"'
#alias dev3='autologin root@host 22 "密码"'
#alias dev4='autologin user jumper 22 pass host "" "cd /home/work && clear"'
#alias dev5='autologin user jumper 22 pass work@host'
文档信息
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)