循环通过多个可能的凭据 TCL Expect

Cycle through multiple possible credentials TCL Expect

我写了一个脚本来通过 ssh 和 运行 一些命令登录。我的设备列表中的一半设备具有不同的可接受用户名和密码组合。

我希望能够解释失败的登录,使用同一设备开始新的登录尝试,但在第二次尝试时使用不同的登录凭据(有两种可能的用户名和密码组合)

如果有人能指出正确的方向,我将不胜感激。这是我第一次使用TCL或expect。

下面是我目前所拥有内容的浓缩版。

set username "someusername"
set password "somepassword"

set devices "X.X.X.X"

foreach device $devices {
    puts "Processing device: $device";
    spawn plink  -ssh $devices 

    expect "Store key in cache"
    send "y\r"

    expect "login as:"
    send "$username\r"

    expect "password:"
    send "$password\r"
    expect "#"

send "conf t\r"
expect "(config)#"

send "some commands\r"
expect "(config)#"

send "end\r"
expect "#"

send "copy run startup-config\r"
expect "#"

你可能需要这样的东西

set usernames [list name1 name2]
set passwords [list pw1   pw2  ]

set devices [list X.X.X.X ...]

foreach device $devices {
    puts "Processing device: $device";
    spawn plink  -ssh $devices 

    set auth_idx -1

    expect {
        "Store key in cache" {send "y\r"; exp_continue}

        "login as:" {
            incr auth_idx
            if {$auth_idx == [llength $usernames]} {
                puts "login failed for $device"

                # close the plink connection. I'm guessing here
                send [=10=]3       ;# Ctrl-C
                expect eof

                # and on to the next device
                continue
            }

            send "[lindex $usernames $auth_idx]\r"
            expect "password:"
            send "[lindex $passwords $auth_idx]\r"

            # and wait for either the command prompt or another login prompt
            exp_continue
        }

        "#"
    }

    # ... whatever you do when you're logged in

    # and logout. something like
    send "quit\r"
    expect eof
}

这在同一 expect 语句中使用 exp_continue 到 "loop"。我假设您可能不必总是将密钥存储在缓存中。如果第一次登录尝试失败

,我还假设您会看到 "login as"

更新

set usernames [list name1 name2]
set passwords [list pw1   pw2  ]

set devices [list X.X.X.X ...]

set device_idx 0
set auth_idx 0

while {$device_idx < [llength $devices]} {
    set device [lindex $devices $device_idx]

    puts "Processing device: $device";
    spawn plink  -ssh $devices 

    expect {
        "Store key in cache" {send "y\r"; exp_continue}

        "login as:" {
            send "[lindex $usernames $auth_idx]\r"
            expect "password:"
            send "[lindex $passwords $auth_idx]\r"
            exp_continue
        }

        "Access denied" {
            incr auth_idx
            if {$auth_idx == [llength $usernames]} {
                puts "login failed for $device"
                # next device
                set auth_idx 0
                incr device_idx
            } else {
                # close the plink connection. I'm guessing here
                send [=11=]3       ;# Ctrl-C
                expect eof
                # re-do with current device
            }
            continue
        }

        "#"
    }

    # ... whatever you do when you're logged in

    # and logout. something like
    send "quit\r"
    expect eof

    # and on to the next device
    set auth_idx 0
    incr device_idx
}