Возможности Expect по управлению сетью

Инструмент, использующий сценарии, автоматизирует операции с командной строкой

Expect – это незаменимый инструмент для эффективного управления системой и сетью, хотя часто его возможности сильно недооценивают. В этой статье дается представление о потенциале Expect на примере решения нескольких типичных задач. Если вам приходится администрировать локальную сеть, то Expect – это незаменимое средство.

Камерон Лейрд, вице-президент, Phaseit, Inc

Камерон Лейрд (Cameron Laird) – давний сотрудник и бывший обозреватель developerWorks. Он часто пишет о проектах с открытыми исходными кодами, которые ускоряют разработку приложений его работодателя, сфокусированных на надёжности и безопасности.



16.02.2009

Если вам приходится администрировать локальную сеть, то Expect – это незаменимое средство.

Другими словами, почему вы еще не используете Expect? Благодаря этому экономится большое количество времени. А если Expect уже используется, то, скорее всего, без учета тех его возможностей, которые будут описаны ниже.

Expect: автоматизация взаимодействия с командной строкой

Необязательно знать все возможности Expect, чтобы получить пользу от его применения. Далее будет приведен конкретный пример, демонстрирующий, как Expect может упростить работу в операционной системе AIX® или любой другой операционной системе.

Допустим, имеется несколько учетных записей на компьютерах с UNIX® или UNIX-подобной ОС и требуется сменить пароли этих учетных записей, но эти учетные записи не синхронизируются NIS (Network Information Service), LDAP (Lightweight Directory Access Protocol) или любой другой системой авторизации, способной определить, что это один и тот же пользователь подключается к разным компьютерам. Подключение к конкретной системе и выполнение на ней команды passwd не займет много времени, несколько минут в большинстве случаев. И все же обязательно необходимо выполнить операцию входа в систему "вручную" из-за того, что не существует сценария удаленной смены пароля.

Не стоит делать категорических выводов – сценарий существует. В стандартную поставку Expect (здесь имеется в виду полная комплектация) включен инструментарий для работы с командной строкой (а также раздел справочника, описывающий его использование), который однозначно облегчит повседневный труд. passmass (см. раздел Ресурсы) – это маленький сценарий, написанный на Expect и позволяющий сменить пароль на двадцати компьютерах за один раз. Вместо того чтобы вводить пароль множество раз, можно один раз запустить passmass, и тогда на всех системах пароль автоматически обновится. При этом экономится достаточно времени для того чтобы сходить прогуляться, и исчезает риск ошибки, когда для одной из систем задается неверный пароль.

Ограничения, накладываемые Expect

Приложение passmass – очень удачный пример для иллюстрации большинства возможностей Expect.

  • Экономия средств: сама утилита уже написана, доступна для свободного скачивания, легко устанавливается и бережет время и нервы.
  • В определенном смысле его можно назвать альтернативным решением. Если бы все делалось "по учебнику" и все уже было организованно через NIS или через общую доменную авторизацию или просто использовалась single sign-on или уже применялась авторизация через систему сценариев, то, возможно, никогда не понадобилось бы использовать passmass. Но, к сожалению, в действительности такая ситуация встречается далеко не всегда, а Expect – это тот инструмент, который позволит сгладить все острые края. Возможно, что Expect поможет просто высвободить достаточно времени для создания более рациональной конфигурации сети, после которой он больше не понадобится. В любом случае хуже не будет.
  • passmass, как он поставляется, умеет работать только с telnet, rlogin и slogin. Я полагаю, что все читатели developerWorks уже сменили их на ssh, который passmass поддерживает не полностью.
  • С другой стороны, решения для большинства задач уже написаны на Expect и находятся в свободном доступе. В нашем случае потребуется дописать всего три строки, чтобы включить в сценарий поддержку ssh.

Возможно, у читателя уже достаточно знаний, чтобы написать или изменить необходимый сценарий Expect. Если это так, то passmass уже содержит необходимый код для поддержки ssh, но, к сожалению, пока отсутствует код, анализирующий командную строку. В листинге 1 описан один из способов, как можно изменить исходный код passmass и добавить ssh в тот же раздел, где расположена поддержка telnet и других протоколов.

Листинг 1. Фрагмент измененной части сценария passmass с поддержкой параметра -ssh
            ...
         } "-rlogin" {
            set login "rlogin"
            continue
        } "-slogin" {
            set login "slogin"
            continue
        } "-ssh" {
            set login "ssh"
            continue
        } "-telnet" {
            set login "telnet"
            continue
           ...

В коде программы обычно большую часть программы принято выносить в модули. Но сейчас этот каскад условий, приблизительно начинающийся с сотой строки сценария, необходим для демонстрации удобочитаемости Expect. Здесь нет сложного программирования – нет никакой нужды в объектах, монолитных приложениях, перекрестных объявлениях и других тонкостях. Компьютер просто сделает то, что обычно делает пользователь. Если это будет реализовано, этот маленький шаг сохранит минуты, а может быть и часы человеческих усилий.

Что такое Expect?

Чем же на самом деле является Expect, и как заставить его решать поставленные задачи?

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

  • Expect – это язык программирования высокого уровня с синтаксисом, идентичным Tcl и добавлением нескольких специальных инструкций, отсутствующих в Tcl.
  • Expect – это исполняемый файл, реализующий возможности одноименного языка и корректно распознающий исходный код, написанный на языке Expect.
  • expect – название одной команды из группы, которой Expect расширяет язык Tcl.
  • Expect – это пакет языка Tcl. Не вдаваясь в тонкости, это толкование можно понимать как возможность Tcl- приложения подгружать необходимую функцию Expect во время работы программы.
  • Expect – это библиотека, написанная на С, которая входит как в состав подгружаемого пакета, так и в состав исполняемого файла.
  • Expect – это общее название инструментов, реализующих:
    • автоматизацию взаимодействия с терминалом, даже если для этого необходим ввод пароля или выполнение иных условий;
    • диалоговую модель взаимодействия, которая основывается на простом ритме запросов и ответов.
    Нет никаких особых причин выбирать именно Tcl, на данный момент существует множество независимых реализаций модели Expect на таких языках как Python, Perl и т.д. Все примеры, обсуждаемые в этой статье, реализованы на Tcl версии Expect, но могут быть с таким же успехом выполнены и на другом языке. Нет необходимости подробно знакомиться с Tcl, так как его незнание не помешает использовать Expect.

Стоит учесть, что опущены несколько технических деталей, не являющихся ключевыми для этой статьи. Например, Expect не только расширяет список команд Tcl, но также в состоянии распознать дополнительные аргументы командной строки при запуске интерпретатора. Однако главная цель не они, а маленький Expect, способный сделать гораздо больше для управления системой, чем большинство специальных программ.

На фоне всего вышесказанного расшифруем значение фразы "passmass это приложение Expect":

  • - passmass – это обычный текстовый файл, написанный на языке Expect;
  • если запустить файл passmass на выполнение в системе с предварительно установленным интерпретатором Expect, то получится результат работы программы passmass.

Стоит отметить, что запустить passmass на исполнение можно несколькими способами: запустить его в интерактивной среде Tcl, просто выполнить команду passmass, набрав ее на терминале, создать самостоятельный исполняемый файл и т.д. Но опять же, обсуждение способов выполнения программ Expect не является основной целью статьи.

Пример работы с сетью

Далее подробно рассмотрена одна из задач, ежедневно решаемых в центре обработки данных: получение текущих настроек нескольких управляемых коммутаторов Cisco. Хотя в некоторых компаниях для решения этой задачи используются протоколы SNMP и HTML, все же наиболее часто для этого используется консоль или подключение к telnet-сеансу для получения информации. Большинство системных администраторов используют только проверенный временем способ, который выглядит примерно как в листинге 2.

Листинг 2. Типичный способ получения конфигурации вручную.
        telnet $MY_ROUTER
        [User: admin]
        [password: ...]
        CCNA01# show running-config
        [... Current configuration:
         ... version 12.0 ...
         FIFTY LINES MORE OF CONFIGURATION DETAIL
         ...
         End]

Но это не совсем верный подход. На самом деле процесс можно полностью автоматизировать и передать на выполнение в cron, почтовому серверу или в любой другой механизм контроля задач (листинг 3).

Листинг 3. Автоматизация получения текущей конфигурации
      #!/usr/bin/expect

      # initialize host, password, ...

      package require Expect
      set prompt {[00m# }
      spawn telnet $host
      expect {User: }
      send admin\r
      expect password:
      send $password\r
      expect -exact $prompt
      send "show running-config\r"
      expect -exact $prompt
      send exit\r

Этот сценарий будет получать нужные данные, не требуя внимания после того как он будет написан и отлажен. Нет никакой необходимости отслеживать его работу или вводить имя и пароль для авторизации или производить какие-либо дополнительные манипуляции.

Ошибки и заблуждения

Этот типичный для Expect пример автоматизации заслужил упоминания по нескольким причинам. Во-первых, не существует общепринятого метода действий. Довольно много системных администраторов начинают использовать Expect полагая, что это инструмент, способный в одиночку решить текущую задачу. Но это не так. Expect совсем не похож, например, на электронный металлоискатель, на законченное решение для поиска потерянных гвоздей. Expect – это, скорее, ручная дрель, инструмент, пользоваться которым можно с помощью различных насадок.

Как и дрель, Expect требует небольшой предварительной настройки. Конечно, Expect можно использовать для решения проблем, которые не так просто решить с помощью других средств. Случай с сценарием running-config показал, как с помощью всего нескольких строк на языке Expect можно собрать богатый урожай на поле автоматизации сбора информации. Но даже небольшой пример способен поднять некоторые проблемы, связанные с использованием Expect. Такой вид автоматизации требует указания пароля администратора внутри сценария в открытом виде, и тут необходимо понять, насколько применимо это решение в текущем окружении.

Существует еще несколько случаев, для которых эта ситуация типична. Значение параметра $prompt удивило меня. На экране оно выглядело как CCNA01#; вполне обычно для большинства устройств, но помимо этого оно содержало еще и невидимые управляющие символы. К счастью, Expect имеет очень полезные операторы для отладки, сообщающие все о его активности. Именно с их помощью было установлено, какая последовательность символов была правильной для CCNA01.

Как видно из листинга 3, на выход подается весь telnet-сеанс целиком, в который помимо ожидаемых отчетов о конфигурации входит авторизация и завершение сессии. Еще одна часто встречающаяся при работе с Expect проблема – это его поведение при выполнении стандартного запроса "получить значение команды". Expect просто-напросто не имеет необходимой семантики для их разбора. При вводе команды с клавиатуры пользователь обычно соотносит свои действия с тем, что видит на экране, прежде чем ввести следующую команду. Для сетевых протоколов, таких как telnet, нет никакой разницы между результатом и приглашением командной строки, которые может различить пользователь.

Из необходимости совместимости с моделью сетевого взаимодействия Expect не делает различий между результатом и приглашением командной строки. Все, что умеет Expect – это вести диалог, состоящий из последовательности отправляемых (sent) и получаемых (expected) символов. На практике используется разбор строк с помощью регулярных выражений, чтобы выделить ожидаемую строку. Expect может похвастаться расширенной поддержкой регулярных выражений и легким преобразованием их в код. Далее в статье внимание читателя фокусируется на обширной теме автоматизации процессов, которые обычно не укладываются в сценарии.

Параллелизм

Напомним, что Expect – это очень мощный язык общего назначения. Полноценные приложения Expect могут, помимо прочего, понимать аргументы командной строки, форматировать результат в столбцы, извлекать сохраненные данные из базы данных, отображать графический интерфейс пользователя. Все вышеназванное – это самые обычные задачи, но они не включены в примеры этой статьи, цель которой – правильно объяснить уникальные стороны Expect.

Сетевой администратор, вооруженный "руководством к действию", таким как листинг 3, обычно думает о возможностях "горизонтального" масштабирования, увеличивая число опрашиваемых компьютеров до десятков и тысяч. Для этих целей имеются конструкции foreach, while и т.д., упрощающие такое расширение.

Но все может быстро привести к серьезным проблемам. Предположим, что необходимо опросить сотню машин в сети (кстати, не такая уж редкая задача). И есть сценарий на Expect, автоматически авторизующийся на каждой машине и получающий необходимые данные. Остается только передать в сценарий список компьютеров и выполнить по нему итерацию.

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

Рассмотрим такой способ. Так уж получилось, что Expect имеет отличные средства для поддержания сразу нескольких диалогов. Ниже приведен пример программы, которая авторизуется сразу на нескольких системах, запрашивает данные на каждой из удаленных машин, а затем получает их назад в порядке поступления. Этот сценарий изменен таким образом, чтобы результаты возвращались в порядке, обратном порядку запросов (листинг 4).

Листинг 4. Параллельное получение отчетов от нескольких систем
       #!/home/claird/local/ActiveTcl/bin/tclsh 
       
       package require Expect
       
       log_user 0
       
       # инициализация имени пользователя и пароля.
       
           # последовательное подключение к системам и запуск на них 
           # команд, требующих времени на выполнение.
       for {set i 0; set delay 8} {$delay > 0} {incr i; incr delay -1} {
           spawn ssh $user@$host
           set sid($i) $spawn_id
           expect rsa':
           send $passphrase
           expect "Last login"
           expect -ex $prompt
           set active($sid($i)) $i
           send -i $sid($i) "echo `date`; sleep $delay; echo `date`; echo \
           '$delay done on $i.'\r"
       }
       
       while {[llength [array names active]]} {
           expect -i [array names active] -ex $prompt {
                puts "RECEIVED:  $::expect_out(buffer)"
                send -i $expect_out(spawn_id) exit\r
                expect -i $expect_out(spawn_id) eof
                unset active($expect_out(spawn_id))
           }
       }

Если запустить этот сценарий, то в ответ будет получен текст, похожий на листинг 5.

Листинг 5. Результат работы листинга 4
       RECEIVED:  echo `date`; sleep 1; echo `date`; echo '1 done on 7.'
       Mon Apr 23 22:15:15 UTC 2007
       Mon Apr 23 22:15:16 UTC 2007
       1 done on 7.
       RECEIVED:  echo `date`; sleep 2; echo `date`; echo '2 done on 6.'
       Mon Apr 23 22:15:15 UTC 2007
       Mon Apr 23 22:15:17 UTC 2007
       2 done on 6.
       RECEIVED:  echo `date`; sleep 3; echo `date`; echo '3 done on 5.'
       Mon Apr 23 22:15:15 UTC 2007
       Mon Apr 23 22:15:18 UTC 2007
       3 done on 5.
          ...
       RECEIVED:  echo `date`; sleep 8; echo `date`; echo '8 done on 0.'
       Mon Apr 23 22:15:14 UTC 2007
       Mon Apr 23 22:15:22 UTC 2007
       8 done on 0.

С точки зрения программиста, это решение нельзя назвать гибким, поскольку оно предполагает наличие одинаковых связок имени и пароля на каждой из опрашиваемых машин, а также взаимодействие по протоколу ssh. На практике с помощью нескольких дополнительных строк кода можно управлять системами с различными протоколами и паролями для авторизации. Также имеет смысл сделать паузу на несколько секунд и повторить запрос. Команда sleep отлично подходит для этого и часто используется вместе с командами, применяемыми системными администраторами.

И даже этот пример не раскрывает всех возможностей Expect. Expect также имеет возможность работать со стеком TCP/IP напрямую через API для программирования сокетов. Также он может работать в полуавтоматическом режиме, переключаясь между режимом, когда пользователь вводит фрагменты диалога, и когда Expect делает все автоматически.

Но это уже тема другой статьи. А эта статья демонстрирует, насколько больше можно сделать с помощью Expect, чем многие администраторы полагают, и как изучение этого инструмента повышает скорость решения большинства проблем при управлении сетью. Такие возможности как указание пароля в сценарии и его ввод или одновременное управление несколькими соединениями очень эффективны.

Summary

Expect позволяет автоматизировать такие задачи, которые на первый взгляд автоматизировать нельзя, например: сценарии ввода пароля, подключение к удаленному сеансу пользователя с последующим возвращением ему контроля и еще множество подобных операций. Как бы широко он ни применялся, большинство сетевых администраторов плохо представляют возможности Expect. В то же время правильное понимание всего лишь нескольких базовых принципов работы (способы запуска, модель взаимодействия и его программный инструментарий) дают общее представление о его потенциале для системного и сетевого администрирования.

Ресурсы

Научиться

  • Оригинал статьи: Expect plays a crucial role in network management (EN);
  • Expect: домашняя Web-страница Expect выглядит достаточно консервативно. Разработчики Expect развивают тот продукт, который они выпустили 15 лет назад, поэтому Web-сайт рассчитан на людей, которые смотрят на содержание, а не на глянцевые обложки. (EN)
  • PDSLIB: среди множества пакетов с открытым исходным кодом для AIX, PDSLIB включает и Expeсt, доступный для загрузки. Кроме того, в официальный AIX FAQ, обновление от 2000 г., входит раздел, посвященный Expect. (EN)
  • ActiveTcl: большинство дистрибутивов UNIX поставляются вместе с Expect, но очень часто не с последней его версией. В большинстве случаев самым легким способом обновить Expect будет установка ActiveTcl. ActiveTcl поддерживает все компоненты Expect и доступен на множестве платформ: Windows®, Mac OS X, Linux®, Solaris, AIX и HP-UX. (EN)
  • Exploring Expect: существует всего одна книга, целиком посвященная Expect. Книга оказалась настолько удачно написанной, что обходится без изменений уже второй десяток лет. И, со слов издателя, ежегодно продается несколько тысяч экземпляров этой книги. Это своеобразное достижение очень характерно для Expect в целом: хотя сам Expect сейчас намного более развитый инструмент, чем в 1994 году, когда была издана книга, основные идеи, описанные в ней, остались неизменными и поныне. Don Libes, автор обоих проектов, Expect и Exploring Expect, продолжает их поддерживать. Книга содержит гораздо больше полезной информации, чем эта статья. Одной из целей этой статьи было дать понять, насколько более мощным инструментом станет Expect, если прочитать эту книгу. (EN)
  • manual page for passmass: руководство по сценарию passmass и примеры – хороший пример использования и документирования сценариев Expect, доступные для просмотра on-line. (EN)
  • Productivity tips (EN) (Michael Stutz, developerWorks, cентябрь 2006 г.) – статья содержит рекомендации по использованию Expect для автоматизации работы с командной строкой и еще множество полезных советов по увеличению производительности. Почему этой статье потребовалось в 10 раз больше текста для получения одинаковых результатов? Все из-за недопонимания принципов работы Expect, особенно начинающими пользователями. Expect многое умеет, и поэтому важно понимать, как он работает. Цель статьи – помочь в этом разобраться.
  • Страница Wiki, посвященная Expect содержит несколько интересных комментариев на тему защиты сценариев Expect, получения результатов выполнения единственной команды и т.д.
  • Expect exceeds expectations (EN) (Cameron Laird, developerWorks, апрель 2002): введение в Expect, подчеркивающее его универсальность, другими словами, в статье раскрывается потенциал языка для решения всех видов задач, встающих перед программистом.
  • Android: множество новичков, пришедших в Expect и вдохновленных его инструментарием, пытаются автоматизировать взаимодействие с GUI-приложениями с такой же ловкостью, как они автоматизировали взаимодействия с командной строкой. Но это невозможно. Написание сценариев, работающих с графическим интерфейсом пользователя – это большая проблема, и в этой статье она не рассматривается. Среди множества разработок, направленных на решение этой задачи, можно выделить проект Android, реализующий интересную среду для работы с GUI. Существуют также и связи между Android и Expect.
  • Tcl: Expect – это расширение Tcl. Это Tcl плюс несколько дополнительных возможностей для управления терминалом, анализа диалогов и отладки. Что такое Tcl? Tcl – это язык программирования высокого уровня и общего назначения, отличающийся легковесностью, портируемостью и простотой в освоении. Это значит, что Expect будет доступен на тех платформах, где доступен Tcl, т.е. на всех вариантах Unix и Windows. Все приложения Expect могут использовать готовый код, написанный на Tcl, так как совместимость с Tcl поддерживается в Expect по умолчанию.
  • Debugging Expect programs (EN): cтатья, освещающая несколько ключевых приемов: autoexpect, exp_internal и interact, большая часть которых специфична именно для Expect.
  • Speaking UNIX, Part 9: Regular Expressions (Martin Streicher, developerWorks, апрель 2007): статья, которая может служить хорошим введением в использование регулярных выражений. Кроме того, есть Web-сайт по проблемам, связанным с регулярными выражениями.
  • Другие статьи и учебники, написанные Камероном Лейрдом:
  • Popular content: популярные материалы об AIX и UNIX.(EN)
  • Раздел developerWorks AIX and UNIX содержит сотни информативных статей для читателей начальной, средней и высокой квалификации.
  • Новичок в AIX и UNIX?: страница AIX и UNIX для новичков.
  • AIX 5L Wiki: совместная разработка документации AIX.
  • Разделы библиотеки информации по темам AIX и UNIX:(EN)
  • Safari bookstore: сайт магазина книг по ИТ.(EN)
  • Команда IBM developerWorks проводит по всему миру сотни бесплатных технических консультаций.(EN)
  • Podcasts: аудиозаписи презентаций экспертов IBM.(EN)

Получить продукты и технологии

  • IBM trial software: ознакомительные версии программного обеспечения для разработчиков, которые можно загрузить прямо со страницы сообщества developerWorks.(EN)

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=AIX и UNIX
ArticleID=369794
ArticleTitle=Возможности Expect по управлению сетью
publish-date=02162009