expect

Bash-скрипты, часть 11: expect и автоматизация интерактивных утилит

Утилита Expect позволяет создавать программы, ожидающие вопросов от других программ и дающие им ответы. Expect можно сравнить с роботом, который способен заменить пользователя при взаимодействии со сценариями командной строки. Expect — инструмент, основанный на языке Tcl.

apt-get install expect
yum install expect
#!/usr/bin/expect -f
set timeout -1      #Отключение таймаута
spawn ./questions   #Запуск скрипта questions
expect "Hello, who are you?\r"
send -- "Im Adam\r"
expect "Can I ask you some questions?\r"
send -- "Sure\r"
expect "What is your favorite topic?\r"
send -- "Technology\r"
expect eof
КомандаОписание
spawnзапуск процесса или программы. Например, это может быть командная оболочка, FTP, Telnet, ssh, scp и так далее.
expectожидание данных, выводимых программой. При написании скрипта можно указать, какого именно вывода он ждёт и как на него нужно реагировать.
sendотправка ответа. Expect-скрипт с помощью этой команды может отправлять входные данные автоматизируемой программе. Она похожа на знакомую вам команду echo в обычных bash-скриптах.
interactпозволяет переключиться на «ручной» режим управления программой.

Autoexpect позволяет запускать программы, которые надо автоматизировать, после чего записывает то, что они выводят, и то, что пользователь вводит, отвечая на их вопросы. Вызовем autoexpect, передав этой утилите имя нашего скрипта:

$ autoexpect ./questions
#!/usr/bin/expect
 
set cmd [lindex $argv 0];
 
spawn telnet localhost 106
 
expect "200" {
        send "USER postmaster\n"
}
 
expect "300" {
        send "PASS Pa\$\$w0rd\n"
}
 
expect "200" {
        send "$cmd\n\n"
}
 
expect "200" {}
 
sleep 1
send "QUIT\n"
send_user "\n"
exit 0
#!/usr/bin/expect
 
set username "admin"
set secret "admin"
set host "127.0.0.1"
set port "5038"
 
set channel [lindex $argv 0];
set num [lindex $argv 1];
set name [lindex $argv 2];
 
send_user "Args: $channel $num $name\n"
 
spawn telnet $host $port
 
expect "Manager" {
        send "Action: Login\n"
        send "Username: $username\n"
        send "Secret: $secret\n\n"
}
 
expect "Response: Success" {
        send "Action: Originate\n"
        send "Channel: SIP/$channel\n"
        send "Context: default\n"
        send "Exten: $num\n"
        send "Callerid: $name<$num>\n"
        send "Priority: 1\n\n"
}
 
sleep 1
 
send "Action: Logoff\n\n"
 
exit 0
#!/usr/bin/expect
 
set email [lindex $argv 0];
set password [lindex $argv 1];
 
spawn docker exec -it greenlight-v2 bash
send "\n"
expect "bash*#" {send "bundle exec rails c\n"}
expect "irb*>" { send "User.find_by(email: \"$email\").update_attribute(:password,\"$password\")\n" }
expect "irb*>" { send "exit\n" }
expect "bash*#" { send "exit\n" }
send_user "\n"
exit 0