2016-02-24 5 views
-1

Я написал сценарий для входа через ssh и выполнения некоторых команд. Половина устройств в списке моего списка устройств имеет другую приемлемую комбинацию имени пользователя и пароля.Цикл через несколько возможных учетных данных TCL Expect

Я хочу, чтобы ожидать, чтобы иметь возможность интерпретировать отказавший вход, начать новую попытку входа в систему с тем же устройством, но и использовать различные учетные данные для входа на второй попытки (есть два возможных имени пользователя и пароля комбинации)

Если любой может указать мне в правильном направлении, я бы очень признателен. Это мой первый опыт использования TCL или ожидания.

Конденсированный вариант того, что я до сих пор ниже.

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 "#" 
+0

Знаете ли вы, что 'foreach' может перебирать два или несколько списков сразу? 'foreach device $ devices username $ usernames password $ passwords {...}'. Это может сделать это проще ... –

+0

Я не знал этого Донала. Благодаря! Я думаю, что даже если в foreach было более одного списка, TCL прекратил работу после первой неудачной попытки. Более того, устройства Cisco, к которым я подключен, не запрашивают имя пользователя после неправильного пароля, поэтому я думаю, что помимо того, что вы можете передать более одного набора переменных auth, сценарий должен был бы начать новый сеанс с использованием того же $ device из $ devices. Я не уверен, что это так, просто думаю. Если, я не рад, что меня будут настроены прямо. – helloworldhello

ответ

1

Вы, вероятно, нужно что-то вроде

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 \003  ;# 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 
} 

Это использует exp_continue для "петли" в то же ожидать заявление. Я предполагаю, что вам не всегда нужно хранить ключ в кеше. Я также предполагаю, что вы видите «вход в качестве», если первая попытка не удается Войти


UPDATE

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 \003  ;# 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 
} 
+0

Спасибо за сообщение Glenn. Качественный товар.! Эта функциональность «incr auth_inx» выглядит большой частью того, что мне нужно. Если первый вход не удался, мы можем создать новый сеанс, а затем применить второй набор кредитов? Я спрашиваю, потому что целевое устройство не вернется к началу приглашений для входа, оно просто будет запрашивать пароль для имени пользователя, которое было первоначально введено, и есть два разных имени пользователя. т.е. «Войти как: пароль somepass someuser @ somedevice в: Доступ запрещен пароль someuser @ somedevice в: Доступ запрещен пароль someuser @ somedevice в: – helloworldhello

+0

@glenjackman Ваше решение работает! Однако теперь появляется еще одна переменная, и это ответ «Тайм-аут соединения» (когда целевой хост недоступен) Могу ли я добавить «else if» или что-то для его учета? – helloworldhello

+0

Посмотрите, как я проверяю «ключ магазина»? Добавьте еще пару 'pattern {condition}' в команду wait –