Подтвердить что ты не робот

Использование условных операторов внутри 'ожидать'

Мне нужно автоматизировать ведение журнала в сеансе TELNET с помощью ожидать, но мне нужно позаботиться о нескольких паролях для одного и того же имени пользователя.

Здесь поток, который мне нужно создать:

  • Открыть сеанс TELNET до IP
  • Отправить имя пользователя
  • Отправить пароль
  • Неверный пароль? Повторите одно и то же имя пользователя, затем другой пароль
  • Должен успешно войти в систему на этом этапе...

Для чего это стоит, вот что у меня до сих пор:

#!/usr/bin/expect
spawn telnet 192.168.40.100
expect "login:"
send "spongebob\r"
expect "password:"
send "squarepants\r"
expect "login incorrect" {
  expect "login:"
  send "spongebob\r"
  expect "password:"
  send "rhombuspants\r"
}
expect "prompt\>" {
  send_user "success!\r"
}
send "blah...blah...blah\r"

Излишне говорить, что это не работает, и не выглядит очень красивым. Из моих приключений с Google Ожидание кажется чем-то вроде темного искусства. Заранее благодарим любого за помощь в этом вопросе!

4b9b3361

Ответ 1

Имейте в виду Изучение ожидаемого книги для всех ожидающих программистов - неоценимо.

Я переписал ваш код: (untested)

proc login {user pass} {
    expect "login:"
    send "$user\r"
    expect "password:"
    send "$pass\r"
}

set username spongebob 
set passwords {squarepants rhombuspants}
set index 0

spawn telnet 192.168.40.100
login $username [lindex $passwords $index]
expect {
    "login incorrect" {
        send_user "failed with $username:[lindex $passwords $index]\n"
        incr index
        if {$index == [llength $passwords]} {
            error "ran out of possible passwords"
        }
        login $username [lindex $passwords $index]
        exp_continue
    }
    "prompt>" 
}
send_user "success!\n"
# ...

exp_continue возвращается назад к началу блока ожидания - это похоже на инструкцию "redo".

Обратите внимание, что send_user заканчивается на \n not \r

Вам не нужно скрывать символ > в своем приглашении: он не является специальным для Tcl.

Ответ 2

С небольшим треском я нашел решение. Оказывается, в ожидании используется синтаксис TCL, о котором я совсем не знаком:

#!/usr/bin/expect
set pass(0) "squarepants"
set pass(1) "rhombuspants"
set pass(2) "trapezoidpants"
set count 0
set prompt "> "
spawn telnet 192.168.40.100
expect {
  "$prompt" {
    send_user "successfully logged in!\r"
  }
  "password:" {
    send "$pass($count)\r"
    exp_continue
  }
  "login incorrect" {
    incr count
    exp_continue
  }
  "username:" {
    send "spongebob\r"
    exp_continue
  }
}
send "command1\r"
expect "$prompt"
send "command2\r"
expect "$prompt"
send "exit\r"
expect eof
exit

Надеюсь, это будет полезно для других.

Ответ 3

Если вы знаете идентификаторы и пароли пользователей, то вам также следует знать, какие пары userid/password выровнены с какими системами. Я думаю, вам будет лучше поддерживать карту, в которую входит пара пользователей/пароль, с помощью которой система извлекает эту информацию и просто использует правильный вариант.

Итак, поскольку вам явно не нравится мой совет, я предлагаю вам посмотреть страницу wikipedia и выполнить процедуру, которая возвращает 0 в случае успеха и 1, если время ожидания истекает. Это позволит вам обнаружить, когда сбой пароля не был выполнен - ​​время ожидания ожидания ожидания и повторить попытку. Если это полезно, вы можете удалить свой downvote сейчас, когда я его отредактировал.

В ретроспективе вы, вероятно, захотите сделать это в сочетании с картой, так как вам нужно будет обнаружить неудавшийся вход в систему, если пароль был изменен.