6 мар. 2014 г.

Автоматизация скриптов с помощью expect

Недавно открыл для себя интересную консольную утилиту expect. Сия утилита является интерпретатором (со своим языком) для взаимодействия с интерактивными (т. е. требующими какого-либо ввода от пользователя) программами.

Дабы не писать много лишнего, рассмотрим использование expect на примере.

Допустим,
  • есть удалённый sftp-сервер с адресом 192.168.1.2, 
  • к которому у нас есть доступы вида user/SECRET, порт 20022,
  • нам нужно автоматически брать с этого сервера файл вида TODAYDATE_smtng_important.txt, где TODAYDATE - текущая дата вида YYYYMMDD, 
  • файлик лежит в корневой директории.
При авторизации на sftp-сервере требуется ввод пароля, который никак ни опцией ни указать, ни ключ не прокинуть (предположим, нет административного доступа на sftp-сервер).

Вот именно здесь в автоматизации этой задачи поможет нам линуксовая консольная утилита expect.

создаем файл get_file.sh со следующим содержимым:

#!/usr/bin/expect
# Script to get important file from sftp quetly. Uses expect (yum install expect -y)
# Usage: ./get_file.sh YYYYMMDD
# where YYYYMMDD - today's date

set today [lindex $argv 0]
spawn sftp -oPort=20022 user@192.168.1.2:${today}_smtng_important.txt /home/user/${today}_smtng_important.txt
expect "password:"
send "SECRET\n";
interact

Строки после комментария:
  1. Создаем переменную today, присваивая ей первый аргумент, переданный скрипту при запуске.
  2. Выполняем команду для подключения к sftp, где вместо ${today} интерпретатор вставляет значение даты (переданное скрипту)
  3. Далее скрипт ждет указанного запроса (prompt) - здесь возможно много вариантов, в т. ч. и таймауты и различные prompt-ы, об этом можно прочитать в мане или в более расширенных статьях.
  4. Получив указанный выше промпт, посылаем в ответ наш пароль и знак окончания строки (аналог нажатия пользователем [Enter])
  5. Далее скрипт полностью передает управление пользователю.
Запускать скрипт, понятное дело после chmod o+x, например так:

./get_file.sh 20142902

Минусом изложенного подхода, конечно же, является хранение пароля для sftp в открытом, не зашифрованном виде.

Ссылки:

  1. Хорошая статья по командам expect
  2. Туториал по expect
  3. Ман по sftp в Linux