Expect — это расширение языка сценариев Tcl , написанное Доном Либесом . [2] Программа автоматизирует взаимодействие с программами, которые предоставляют интерфейс текстового терминала . Expect, изначально написанный в 1990 году для платформы Unix , с тех пор стал доступен для Microsoft Windows и других систем.
Expect используется для автоматизации управления интерактивными приложениями , такими как Telnet , FTP , passwd , fsck , rlogin , tip , SSH и другими. [3] Expect использует псевдотерминалы (Unix) или эмулирует консоль (Windows), запускает целевую программу, а затем взаимодействует с ней, как это делает человек, через интерфейс терминала или консоли. [4] Tk , еще одно расширение Tcl, может использоваться для предоставления графического пользовательского интерфейса . [5]
Expect служит «клеем» для связывания существующих утилит. Общая идея заключается в том, чтобы выяснить, как заставить Expect использовать существующие инструменты системы, а не в том, чтобы выяснить, как решить проблему внутри Expect.
Ключевое использование Expect включает коммерческие программные продукты. Многие из этих продуктов предоставляют некоторый тип интерфейса командной строки, но им обычно не хватает мощности, необходимой для написания скриптов . Они были созданы для обслуживания пользователей, администрирующих продукт, но компания часто не тратит ресурсы на полную реализацию надежного языка сценариев. Скрипт Expect может порождать оболочку, искать переменные среды, выполнять некоторые команды Unix для получения дополнительной информации, а затем входить в интерфейс командной строки продукта, вооруженный необходимой информацией для достижения цели пользователя. После получения информации путем взаимодействия с продуктом через его интерфейс командной строки скрипт может принимать разумные решения о том, какие действия следует предпринять, если таковые имеются.
Каждый раз, когда операция Expect завершается, результаты сохраняются в локальной переменной $expect_out. Это позволяет скрипту собирать информацию для обратной связи с пользователем, а также позволяет условное поведение того, что отправлять дальше, в зависимости от обстоятельств.
Обычно Expect используется для настройки тестового набора для программ, утилит или встроенных систем. DejaGnu — это тестовый набор, написанный с использованием Expect для использования в тестировании. Он использовался для тестирования GCC и удаленных целей, таких как встроенная разработка.
Скрипт Expect можно автоматизировать с помощью инструмента под названием «autoexpect». Этот инструмент наблюдает за вашими действиями и генерирует скрипт Expect с использованием эвристики. Хотя сгенерированный код может быть большим и несколько загадочным, всегда можно подправить сгенерированный скрипт, чтобы получить точный код.
# Предположим, что $remote_server, $my_user_id, $my_password и # $my_command были прочитаны ранее в скрипте.# Откройте сеанс Telnet с удаленным сервером и дождитесь # приглашения на ввод имени пользователя. spawn telnet $remote_server expect "username:" # Отправьте имя пользователя и дождитесь запроса пароля. send "$my_user_id\r" expect "password:" # Отправьте пароль и дождитесь приглашения оболочки. send "$my_password\r" expect "%" # Отправьте предварительно созданную команду, а затем подождите # другого приглашения оболочки. send "$my_command\r" expect "%" # Записываем результаты команды в переменную. Это # можно отобразить или записать на диск. set results $expect_out ( buffer ) # Выйти из сеанса Telnet и дождаться специального символа # конца файла. send "exit\r" expect eof
Другой пример — скрипт, автоматизирующий FTP:
# Установите параметр тайм-аута на правильное значение. # Например, размер файла действительно большой, а скорость сети — это действительно проблема, вам лучше установить для этого параметра # значение. set timeout - 1 # Откройте сеанс FTP на удаленном сервере и # дождитесь запроса имени пользователя. spawn ftp $remote_server expect "username:" # Отправьте имя пользователя и дождитесь запроса пароля. send "$my_user_id\r" expect "password:" # Отправьте пароль и дождитесь приглашения 'ftp'. send "$my_password\r" expect "ftp>" # Переключитесь в двоичный режим и дождитесь приглашения 'ftp'. send "bin\r" expect "ftp>" # Отключить подсказки. отправить "prompt\r" ожидать "ftp>" # Получить все файлы отправить "mget *\r" ожидать "ftp>" # Выйти из сеанса FTP и дождаться специального символа # конца файла. send "bye\r" expect eof
Ниже приведен пример автоматизации SFTP (с паролем):
#!/usr/bin/env ожидаем -f# Процедура попытки подключения; результат 0, если все в порядке, 1 в противном случае proc connect { passw } { expect { "Пароль:" { send "$passw\r" expect { "sftp*" { return 0 } } } } # Истекло время ожидания return 1 } # Прочитать входные параметры set user [ lindex $argv 0 ] set passw [ lindex $argv 1 ] set host [ lindex $argv 2 ] set location [ lindex $argv 3 ] set file1 [ lindex $argv 4 ] set file2 [ lindex $argv 5 ] #puts "Аргумент data:\n"; #puts "user: $user"; #puts "passw: $passw"; #puts "host: $host"; #puts "location: $location"; #puts "file1: $file1"; #puts "file2: $file2";# Проверьте, все ли было предоставлено if { $user == "" || $passw == "" || $host == "" || $location == "" || $file1 == "" || $file2 == "" } { puts "Использование: <пользователь> <пароль> <хост> <расположение> <файл1 для отправки> <файл2 для отправки>\n" exit 1 } # sftp на указанный хост и отправка файлов spawn sftp $user @ $host set rez [ connect $passw ] if { $rez == 0 } { send "cd $location\r" set timeout - 1 send "put $file2\r" send "put $file1\r" send "ls -l\r" send "quit\r" expect eof exit 0 } puts "\nОшибка подключения к серверу: $host, пользователь: $user и пароль: $passw!\n" exit 1
Использование паролей в качестве аргументов командной строки, как в этом примере, является огромной дырой в безопасности, поскольку любой другой пользователь на машине может прочитать этот пароль, запустив " ps ". Однако вы можете добавить код, который будет запрашивать ваш пароль, а не предоставлять его в качестве аргумента. Это должно быть более безопасно. Смотрите пример ниже.
stty - echo send_user -- "Введите пароль: " expect_user - re "(.*)\n" send_user "\n" stty echo set PASS $expect_out ( 1 , string )
Еще один пример автоматического входа по SSH на компьютер пользователя:
# Тайм-аут — это предопределенная переменная в Expect, которая по умолчанию # установлена на 10 секунд. # spawn_id — это еще одна предопределенная переменная в Expect. # Хорошей практикой является закрытие дескриптора spawn_id , # созданного командой spawn. set timeout 60 spawn ssh $user @machine while { 1 } { expect { eof {break} "Подлинность хоста" { send "yes\r" } "password:" { send "$password\r" } "*\]" { send "exit\r" } } } wait close $spawn_id
Различные проекты реализуют Expect-подобную функциональность в других языках, таких как C# , Java , Scala , Groovy , Perl , Python , Ruby , Shell и Go . Они, как правило, не являются точными клонами оригинального Expect, но концепции, как правило, очень похожи.
{{cite web}}
: CS1 maint: дата и год ( ссылка )