Использование условных операторов внутри 'ожидать'
Мне нужно автоматизировать ведение журнала в сеансе 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 Ожидание кажется чем-то вроде темного искусства. Заранее благодарим любого за помощь в этом вопросе!
Ответы
Ответ 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 сейчас, когда я его отредактировал.
В ретроспективе вы, вероятно, захотите сделать это в сочетании с картой, так как вам нужно будет обнаружить неудавшийся вход в систему, если пароль был изменен.