Знакомьтесь - Expect

Как часто Вам приходилось заниматься рутинной работой? Не слишком ли много? Может, лучше было бы немного подучить стандартные команды и изучить все их возможности? Типичная ситуация - сервер на чём-нибудь Unix-подобном и куча машин с Windows. К примеру, у Вас установлен AVP и необходимо скачивать все update'ы - как это лучше сделать? Конечно, можно скачивать с помощью AVP Update'а, но тут есть один недостаток - скачивать-то придётся для каждой машины отдельно, да и качество связи в Беларуси, мягко говоря, не самое лучшее (если, конечно, у Вас БелПак, то никаких проблем не будет), поэтому намного лучше скачивать все update'ы на локальный сервер, а оттуда уже устанавливать на все остальные машины (правильно настроив тот же AVP Update). Один из возможных путей решения данной проблемы - воспользоваться одной из "качалок" (к примеру, wget), но есть и другой путь - написать скрипт, который и будет выполнять данную задачу - подобный опыт далеко не лишний.

Чтобы не быть голословным, разберём на примере соединения с ftp-сервером.

>ftp
>open ftp.unibel.by
вводим имя + пароль
>cd /Utils/какой-то-там-каталог
get нужный_нам_файл
quit

Очевидно, что самому сидеть и вводить команды - далеко не лучший выбор. К счастью, практически в каждом (даже, может, в каждом) дистрибутиве Linux'а есть замечательный продукт - expect (англ. ожидать) - он специально предназначен для таких вещей. Эта удобная программа служит для интерактивного взаимодействия с другими программами. Всё, что требуется от человека, - написать скрипт (освоить синтаксис не составит труда любому более или менее знакомому с программированием), согласно которому expect будет "знать", чего ожидать от данной программы и как правильно отвечать на её запросы.

Вот простейший скрипт для реализации вышеизложенного примера:

 
#!/bin/expect -
set timeout 120 #если 2 минут недостаточно, смените канал
spawn ftp ftp.unibel.by #всё логично - запустили ftp-клиент
expect -re "ame" #ожидаем запроса на ввод имени(2 минуты-см.выше)
{
 send - "anonymous\r" #отвечаем на запрос,"\r"-перевод строки.
}
expect -re "assw"
{
 send - "your@mail.com\r" #отправляем e-mail в качестве пароля
}
expect -re ">" #ожидаем приглашения на ввод команд
send - " cd /Utils/какой-то-там-каталог\r"
send - "get нужный_нам_файл\r"
expect -re ">"
send - "quit\r"
close #посылаем запрос на закрытие ftp-клиента
wait #ожидаем закрытия
exit

В общем, из комментариев почти всё ясно (надеюсь). Единственное замечание, которое хотелось бы сделать, так это насчёт close и wait - в данном примере их, в общем-то, можно опустить, т.к. программа сама после этого закрывается и больше ничего не делает, а вот при использовании программ, которые циклически запускают другие программы, это может привести к неприятным последствиям в виде забивания ресурсов системы и/или же аварийного завершения программы.

Разумеется, что скрипт не предусматривает многих вещей - невозможность найти адрес сервера (нестабильно работающий DNS-сервер - не такая уж и редкая ситуация), всевозможные ошибки при передаче и проч., но при написании статьи не ставилась задача рассказать обо всех тонкостях и подводных камнях при написании скриптов, освобождающих от некоторой толики рутинной работы, а лишь показать их некоторые возможности. Изучать ли expect, perl и shell'овские скрипты более углубленно и придумывать им новые сферы применения - личное дело каждого.

Александр ИВАНЮКОВИЧ,
Minsk Linux Users Group,
ivanyukovich@yahoo.com

Версия для печатиВерсия для печати

Номер: 

12 за 2000 год

Рубрика: 

Software
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!