expect 自动登陆脚本 auto_login

使用 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'

文档信息

Search

    Table of Contents