Рано или поздно становится понятно, что многие вещи можно автоматизировать при помощи тех же shell-скриптов, это верно когда дело касается администрирования Linux систем, но что делать когда удаленная система совсем не похожа на linux, например обычная консоль? В этом нам поможет — expect.
Expect — инструмент для автоматизации таких интерактивных приложений, как telnet, ftp, passwd, fsck, rlogin, tip, ssh, и т.д. Основная идея состоит в том, чтобы автоматизировать существующие инструменты, а не изобретать велосипеды по несколько раз.
Для примера давайте попробуем разобрать скрипт для обновления «cisco privilege» на определенном списке оборудования получаемым из списка в файле «ip». Листинг выглядит следующим образом:
#!/usr/bin/expect -f set password mypassword set timeout -1 set ufile [open "./ip" r] foreach uline [split [read $ufile] "\n"] { set SWITCH_IP [lindex $uline 0] if { [string length $SWITCH_IP] > 0 } { spawn telnet $SWITCH_IP #match_max 100000 expect -exact "Username:" {send -- "username\r"} expect -exact "Password:" send -- "$password\r" expect -exact "#" {send -- "conf t\r"} expect -exact "(config)#" {send -- "privilege exec level 4 show ip access-lists\r"} expect -exact "(config)#" {send -- "privilege exec level 4 show access-lists\r"} expect -exact "(config)#" {send -- "exit\r"} expect -exact "#" {send -- "wr\r"} expect -exact "#" {send -- "exit\r"} # interact } } close $ufile expect eof
Как видно из листинга — язык не такой уж сложный.
- В начале идет обязательный заголовок «#!/usr/bin/expect -f».
set password mypassword
- Мы присваиваем переменной «password» значение «mypassword».
Прописывать пароль в коде или задавать его в командной строке, не самое правильное решение с точки зрения безопасности. Правильней спрашивать пароль в самом начале в виде интерактивного сеанса.
set ufile [open "./ip" r] foreach uline [split [read $ufile] "\n"] { set SWITCH_IP [lindex $uline 0]
- Открываем файл «ip», читаем его построчно при этом значение первого столбца записываем в переменную «SWITCH_IP».
if { [string length $SWITCH_IP] > 0 } { spawn telnet $SWITCH_IP
- Если полученный аргумент не пустой, выполняем команду telnet
expect -exact "Username:" {send -- "username\r"} expect -exact "Password:" send -- "$password\r"
- Передаем логин и пароль. Для наглядности в листинге 2 разных способа.
expect -exact "#" {send -- "conf t\r"}
- Ожидаем символа «#», если символ прилетел, то отправляем «conf t\r».
- Повторяем данную операцию несколько раз, но уже с другими командами.
interact
- Уходим в интерактивный режим, если в этом есть необходимость.
close $ufile expect eof
- Закрываем файл и завершаем expect.
Как видно из листинга и описания, скрипт очень простой и требует огромной доработки в плане обработки исключений и особенностей вывода того же оборудования. Несмотря на это пример рабочий, и позволяет существенно экономить сетевых инженеров. Но, в тоже время, это лишь пример или правильней сказать болванка, для ваших дальнейших наработок. В интернете большое количество различных примеров для работы с expect так что — дерзайте!