Введение
В этой лабораторной работе вы узнаете, как использовать команду Linux expect для автоматизации интерактивных приложений командной строки. Команда expect — это мощный инструмент автоматизации, который позволяет скриптам взаимодействовать с программами, требующими ввода данных пользователем, такими как SSH, FTP и другие интерактивные программы.
К концу этой лабораторной работы вы сможете:
- Понимать назначение и базовый синтаксис команды
expect - Создавать скрипты для автоматизации входа в систему SSH
- Обрабатывать различные запросы и ответы в ваших скриптах
expect
Команда expect может значительно сократить ручное вмешательство для повторяющихся задач, делая администрирование системы и рутинные задачи более эффективными. Вы начнете с установки и изучения базового синтаксиса expect, а затем перейдете к созданию скриптов для автоматизации входа в систему SSH и обработки различных интерактивных запросов.
Понимание команды expect и ее базового синтаксиса
Команда expect в Linux позволяет автоматизировать интерактивные программы командной строки, которые обычно требуют ввода данных пользователем. Это особенно полезно для таких задач, как автоматический вход в систему, передача файлов или любая ситуация, когда программа запрашивает ввод.
Установка expect
Сначала давайте убедимся, что пакет expect установлен в нашей системе. Откройте терминал и выполните:
which expect
Если expect уже установлен, вы увидите его путь (например, /usr/bin/expect). Если нет, вам потребуется установить его:
sudo apt-get update
sudo apt-get install -y expect
Понимание базового синтаксиса expect
Команда expect использует язык сценариев, основанный на Tcl (Tool Command Language). Базовая структура скрипта expect включает следующие команды:
spawn: Запускает процесс для взаимодействияexpect: Ожидает определенный вывод от запущенного процессаsend: Отправляет ввод запущенному процессуset timeout: Устанавливает время ожидания ожидаемого вывода
Давайте создадим простой скрипт expect, чтобы продемонстрировать эти концепции. Откройте текстовый редактор и создайте файл с именем hello.exp в вашем каталоге проекта:
cd ~/project
nano hello.exp
Введите следующее содержимое в файл:
#!/usr/bin/expect -f
## Set a timeout of 10 seconds
set timeout 10
## Spawn the bash process
spawn bash
## Wait for the bash prompt
expect "$ "
## Send a command to the bash process
send "echo Hello from expect\r"
## Wait for the bash prompt again
expect "$ "
## Exit the bash session
send "exit\r"
## Wait for the process to complete
expect eof
Сохраните файл, нажав Ctrl+O, затем Enter, и выйдите из nano с помощью Ctrl+X.
Сделайте скрипт исполняемым:
chmod +x ~/project/hello.exp
Теперь запустите скрипт:
~/project/hello.exp
Вы должны увидеть вывод, похожий на этот:
spawn bash
$ echo Hello from expect
Hello from expect
$ exit
exit
Понимание каждой строки скрипта
Позвольте мне объяснить, что делает каждая строка в скрипте:
#!/usr/bin/expect -f: Это строка shebang, которая указывает системе использовать интерпретаторexpectдля запуска этого скрипта.set timeout 10: Это устанавливает таймаут в 10 секунд для любой командыexpect, которая следует за ней.spawn bash: Это запускает новый процесс оболочки bash, с которым будет взаимодействоватьexpect.expect "$ ": Это ожидает появления приглашения bash.send "echo Hello from expect\r": Это отправляет команду в оболочку bash. Обратите внимание на\rв конце, который имитирует нажатие клавиши Enter.expect "$ ": Это снова ожидает приглашения bash после выполнения команды.send "exit\r": Это отправляет команду exit для закрытия оболочки bash.expect eof: Это ожидает завершения запущенного процесса.
Этот простой пример демонстрирует основную функциональность expect. В следующих шагах мы будем использовать эти концепции для создания более практичных скриптов.
Создание скрипта имитации входа в систему SSH с помощью expect
На этом этапе мы создадим скрипт expect, который имитирует процесс входа в систему SSH. Поскольку мы не можем выполнить фактический вход в систему SSH в этой среде, мы создадим имитационный скрипт, демонстрирующий принципы.
Понимание потока аутентификации SSH
При подключении к удаленному серверу через SSH типичное взаимодействие включает в себя:
- Инициирование соединения с помощью
ssh username@hostname - Принятие ключа хоста (если подключение выполняется впервые)
- Ввод пароля по запросу
- Получение доступа к удаленной оболочке
Давайте создадим имитационную среду SSH, чтобы продемонстрировать, как expect может автоматизировать этот процесс.
Создание скрипта имитации SSH-сервера
Сначала давайте создадим скрипт, который имитирует SSH-сервер, запрашивающий пароль:
cd ~/project
nano mock_ssh_server.sh
Введите следующее содержимое:
#!/bin/bash
echo "The authenticity of host 'mockserver' can't be established."
echo "RSA key fingerprint is SHA256:abcdefghijklmnopqrstuvwxyz123456."
echo "Are you sure you want to continue connecting (yes/no)? "
read answer
if [ "$answer" != "yes" ]; then
echo "Host key verification failed."
exit 1
fi
echo "Warning: Permanently added 'mockserver' (RSA) to the list of known hosts."
echo "Password: "
read -s password
if [ "$password" == "mockpassword" ]; then
echo "Last login: Wed Nov 1 12:00:00 2023 from 192.168.1.100"
echo "Welcome to Mock SSH Server"
echo "mockuser@mockserver:~$ "
while true; do
read -p "" command
if [ "$command" == "exit" ]; then
echo "Connection to mockserver closed."
exit 0
else
echo "Executing: $command"
echo "mockuser@mockserver:~$ "
fi
done
else
echo "Permission denied, please try again."
exit 1
fi
Сохраните файл и сделайте его исполняемым:
chmod +x ~/project/mock_ssh_server.sh
Этот скрипт имитирует:
- Запрос проверки хоста SSH
- Запрос пароля
- Простую оболочку, которая отвечает на команды
Создание скрипта expect для автоматизации входа в систему
Теперь давайте создадим скрипт expect, который автоматизирует взаимодействие с нашим имитационным SSH-сервером:
cd ~/project
nano ssh_login.exp
Введите следующее содержимое:
#!/usr/bin/expect -f
## Set variables
set timeout 10
set password "mockpassword"
## Start the mock SSH server
spawn ./mock_ssh_server.sh
## Handle the host verification prompt
expect "Are you sure you want to continue connecting (yes/no)? "
send "yes\r"
## Handle the password prompt
expect "Password: "
send "$password\r"
## Wait for the shell prompt
expect "mockuser@mockserver:~$ "
## Execute a command
send "ls -la\r"
expect "mockuser@mockserver:~$ "
## Exit the session
send "exit\r"
## Wait for the process to complete
expect eof
puts "\nSSH login automation completed successfully!"
Сохраните файл и сделайте его исполняемым:
chmod +x ~/project/ssh_login.exp
Запуск скрипта автоматического входа в систему
Теперь давайте запустим наш скрипт expect, чтобы автоматизировать взаимодействие с имитационным SSH-сервером:
cd ~/project
./ssh_login.exp
Вы должны увидеть вывод, похожий на этот:
spawn ./mock_ssh_server.sh
The authenticity of host 'mockserver' can't be established.
RSA key fingerprint is SHA256:abcdefghijklmnopqrstuvwxyz123456.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'mockserver' (RSA) to the list of known hosts.
Password:
Last login: Wed Nov 1 12:00:00 2023 from 192.168.1.100
Welcome to Mock SSH Server
mockuser@mockserver:~$ ls -la
Executing: ls -la
mockuser@mockserver:~$ exit
Connection to mockserver closed.
SSH login automation completed successfully!
Объяснение скрипта
Позвольте мне объяснить, что делает каждая часть нашего скрипта expect:
set timeout 10: Устанавливает глобальный таймаут в 10 секунд для всех командexpect.set password "mockpassword": Сохраняет пароль в переменной.spawn ./mock_ssh_server.sh: Запускает наш скрипт имитации SSH-сервера.expect "Are you sure you want to continue connecting (yes/no)? ": Ожидает запроса проверки хоста.send "yes\r": Отправляет "yes", чтобы принять ключ хоста.expect "Password: ": Ожидает запроса пароля.send "$password\r": Отправляет пароль.expect "mockuser@mockserver:~$ ": Ожидает приглашения оболочки.send "ls -la\r": Отправляет команду для вывода списка файлов.expect "mockuser@mockserver:~$ ": Снова ожидает приглашения оболочки.send "exit\r": Отправляет команду exit для закрытия сеанса.expect eof: Ожидает завершения процесса.puts "\nSSH login automation completed successfully!": Выводит сообщение об успехе.
Этот пример демонстрирует, как expect можно использовать для автоматизации всего процесса входа в систему SSH, от принятия ключа хоста до выполнения команд на удаленном сервере и безопасного выхода.
Обработка нескольких запросов и ответов с помощью expect
В реальных сценариях интерактивные программы часто отображают несколько запросов и могут требовать разных ответов в зависимости от различных условий. На этом этапе мы узнаем, как обрабатывать несколько запросов и условные ответы в скриптах expect.
Понимание условных блоков expect
Команда expect может использоваться со структурой блок-действие для обработки различных возможных запросов:
expect {
"pattern1" { actions for pattern1 }
"pattern2" { actions for pattern2 }
timeout { actions for timeout }
eof { actions for end of file }
}
Эта структура позволяет вашему скрипту реагировать по-разному в зависимости от полученного вывода.
Создание скрипта обработки нескольких запросов
Давайте создадим скрипт, который имитирует программу с несколькими запросами:
cd ~/project
nano multi_prompt.sh
Введите следующее содержимое:
#!/bin/bash
echo "Please select an option:"
echo "1. Show date and time"
echo "2. List files"
echo "3. Show system info"
echo "4. Exit"
echo -n "Enter your choice (1-4): "
read choice
case $choice in
1)
echo "Current date and time:"
date
;;
2)
echo "File listing:"
ls -la
;;
3)
echo "System information:"
uname -a
;;
4)
echo "Exiting program..."
exit 0
;;
*)
echo "Invalid option. Please enter a number between 1 and 4."
exit 1
;;
esac
echo "Do you want to continue? (yes/no): "
read answer
if [ "$answer" == "yes" ]; then
echo "Continuing..."
echo "Operation completed successfully."
else
echo "Exiting program..."
fi
Сохраните файл и сделайте его исполняемым:
chmod +x ~/project/multi_prompt.sh
Теперь давайте создадим скрипт expect для взаимодействия с этой программой и обработки всех возможных запросов:
cd ~/project
nano handle_prompts.exp
Введите следующее содержимое:
#!/usr/bin/expect -f
## Set a timeout
set timeout 10
## Start the multi-prompt program
spawn ./multi_prompt.sh
## Wait for the choice prompt
expect "Enter your choice (1-4): "
## Generate a random choice (1-3)
set choice [expr {int(rand() * 3) + 1}]
send "$choice\r"
## Process the result based on the choice
switch $choice {
1 {
expect "Current date and time:"
expect "Do you want to continue? (yes/no): "
}
2 {
expect "File listing:"
expect "Do you want to continue? (yes/no): "
}
3 {
expect "System information:"
expect "Do you want to continue? (yes/no): "
}
}
## Handle the continue prompt
expect {
"Do you want to continue? (yes/no): " {
## 70% chance to say yes, 30% chance to say no
if {rand() < 0.7} {
send "yes\r"
expect "Operation completed successfully."
} else {
send "no\r"
expect "Exiting program..."
}
}
timeout {
puts "Timeout waiting for continue prompt"
exit 1
}
}
## Wait for the program to complete
expect eof
puts "\nMulti-prompt handling completed successfully!"
Сохраните файл и сделайте его исполняемым:
chmod +x ~/project/handle_prompts.exp
Запуск скрипта обработки нескольких запросов
Теперь давайте запустим наш скрипт expect для взаимодействия с программой с несколькими запросами:
cd ~/project
./handle_prompts.exp
Каждый раз, когда вы запускаете этот скрипт, он случайным образом выбирает один из вариантов и случайным образом решает, продолжать или выйти. Вот пример вывода:
spawn ./multi_prompt.sh
Please select an option:
1. Show date and time
2. List files
3. Show system info
4. Exit
Enter your choice (1-4): 2
File listing:
total 20
drwxr-xr-x 2 labex labex 4096 Nov 1 10:00 .
drwxr-xr-x 4 labex labex 4096 Nov 1 10:00 ..
-rwxr-xr-x 1 labex labex 345 Nov 1 10:00 handle_prompts.exp
-rwxr-xr-x 1 labex labex 578 Nov 1 10:00 multi_prompt.sh
-rwxr-xr-x 1 labex labex 221 Nov 1 10:00 ssh_login.exp
Do you want to continue? (yes/no): yes
Continuing...
Operation completed successfully.
Multi-prompt handling completed successfully!
Создание более продвинутого скрипта expect
Теперь давайте создадим более продвинутый скрипт, который может обрабатывать непредвиденные запросы и ошибки:
cd ~/project
nano advanced_expect.exp
Введите следующее содержимое:
#!/usr/bin/expect -f
## Set a timeout
set timeout 10
## Define variables
set program "./multi_prompt.sh"
set max_retries 3
set retry_count 0
## Define a procedure to handle errors
proc handle_error {} {
global retry_count max_retries program
incr retry_count
if {$retry_count < $max_retries} {
puts "\nRetrying... Attempt $retry_count of $max_retries"
## Start the program again
spawn $program
return 1
} else {
puts "\nMaximum retry attempts reached. Exiting."
exit 1
}
}
## Start the program
spawn $program
## Main interaction loop
while {$retry_count < $max_retries} {
expect {
"Enter your choice (1-4): " {
send "1\r" ## Always choose option 1 for deterministic behavior
}
"Invalid option" {
puts "\nReceived invalid option message."
if {[handle_error]} continue
}
"Current date and time:" {
## Successfully got date output
}
"Do you want to continue? (yes/no): " {
send "yes\r"
}
"Operation completed successfully." {
puts "\nAdvanced expect script completed successfully!"
break
}
timeout {
puts "\nTimeout occurred waiting for prompt."
if {[handle_error]} continue
}
eof {
puts "\nUnexpected end of file."
if {[handle_error]} continue
}
}
}
## Wait for the program to complete
expect eof
Сохраните файл и сделайте его исполняемым:
chmod +x ~/project/advanced_expect.exp
Запустите расширенный скрипт:
cd ~/project
./advanced_expect.exp
Пример вывода:
spawn ./multi_prompt.sh
Please select an option:
1. Show date and time
2. List files
3. Show system info
4. Exit
Enter your choice (1-4): 1
Current date and time:
Wed Nov 1 10:00:00 UTC 2023
Do you want to continue? (yes/no): yes
Continuing...
Operation completed successfully.
Advanced expect script completed successfully!
Понимание расширенного скрипта
Этот расширенный скрипт демонстрирует несколько важных методов expect:
- Обработка ошибок: Он использует механизм повторных попыток для обработки ошибок или непредвиденных ответов.
- Процедуры: Он определяет пользовательскую процедуру под названием
handle_errorдля многократной обработки ошибок. - Управление потоком: Он использует цикл while для поддержания взаимодействия до успеха или максимального количества повторных попыток.
- Несколько шаблонов expect: Он обрабатывает несколько различных шаблонов и выполняет соответствующие действия для каждого.
- Порядок шаблонов: Порядок шаблонов в блоке
expectимеет значение - более конкретные шаблоны должны идти перед более общими.
Эти методы можно применять для автоматизации сложных интерактивных программ, в которых поток может меняться или могут возникать ошибки.
Создание практических скриптов expect для общих задач
На этом этапе мы создадим практические скрипты expect для общих задач, которые системным администраторам часто необходимо автоматизировать. Мы сосредоточимся на операциях с файлами, взаимодействии с пользователями и мониторинге системы.
Автоматизация передачи файлов с помощью expect
Давайте создадим скрипт expect, который автоматизирует передачу файла с помощью команды scp. Поскольку мы не можем выполнить фактическую передачу файла в этой среде, мы будем ее имитировать:
cd ~/project
nano file_transfer.sh
Введите следующее содержимое, чтобы имитировать передачу файла, подобную SCP:
#!/bin/bash
echo "scp file transfer simulation"
echo "Source file: $1"
echo "Destination: $2"
echo "Password: "
read -s password
if [ "$password" == "transfer123" ]; then
echo "Transferring file..."
echo "0%"
sleep 1
echo "25%"
sleep 1
echo "50%"
sleep 1
echo "75%"
sleep 1
echo "100%"
echo "File transfer completed successfully."
else
echo "Authentication failed."
exit 1
fi
Сохраните файл и сделайте его исполняемым:
chmod +x ~/project/file_transfer.sh
Теперь давайте создадим скрипт expect для автоматизации этой передачи файла:
cd ~/project
nano file_transfer.exp
Введите следующее содержимое:
#!/usr/bin/expect -f
## Set variables
set timeout 10
set source_file "local_file.txt"
set destination "user@remote:/path/to/destination/"
set password "transfer123"
## Create a dummy source file
spawn bash -c "echo 'This is a test file' > $source_file"
expect eof
## Start the file transfer simulation
spawn ./file_transfer.sh $source_file $destination
## Handle the password prompt
expect "Password: "
send "$password\r"
## Monitor the transfer progress
expect "0%"
puts "Transfer started..."
expect "25%"
puts "Transfer 1/4 complete..."
expect "50%"
puts "Transfer 1/2 complete..."
expect "75%"
puts "Transfer 3/4 complete..."
expect "100%"
puts "Transfer almost done..."
expect "File transfer completed successfully."
puts "File transfer automation completed!"
## Clean up the dummy file
spawn bash -c "rm $source_file"
expect eof
Сохраните файл и сделайте его исполняемым:
chmod +x ~/project/file_transfer.exp
Запустите скрипт автоматизации передачи файлов:
cd ~/project
./file_transfer.exp
Пример вывода:
spawn bash -c echo 'This is a test file' > local_file.txt
spawn ./file_transfer.sh local_file.txt user@remote:/path/to/destination/
scp file transfer simulation
Source file: local_file.txt
Destination: user@remote:/path/to/destination/
Password:
Transferring file...
0%
Transfer started...
25%
Transfer 1/4 complete...
50%
Transfer 1/2 complete...
75%
Transfer 3/4 complete...
100%
Transfer almost done...
File transfer completed successfully.
File transfer automation completed!
spawn bash -c rm local_file.txt
Автоматизация создания пользователей с помощью expect
Теперь давайте создадим скрипт expect, который автоматизирует создание пользователей. Опять же, мы будем имитировать этот процесс:
cd ~/project
nano create_user.sh
Введите следующее содержимое:
#!/bin/bash
echo "User creation utility"
echo "Please enter new username: "
read username
echo "Please enter password for $username: "
read -s password
echo "Please confirm password: "
read -s password_confirm
if [ "$password" != "$password_confirm" ]; then
echo "Error: Passwords do not match."
exit 1
fi
echo "Creating user $username..."
echo "User $username created successfully."
echo "Do you want to add this user to the sudo group? (yes/no): "
read sudo_choice
if [ "$sudo_choice" == "yes" ]; then
echo "Adding $username to sudo group..."
echo "User $username added to sudo group."
fi
echo "User setup completed."
Сохраните файл и сделайте его исполняемым:
chmod +x ~/project/create_user.sh
Теперь давайте создадим скрипт expect для автоматизации создания пользователей:
cd ~/project
nano create_user.exp
Введите следующее содержимое:
#!/usr/bin/expect -f
## Set variables
set timeout 10
set username "testuser"
set password "P@ssw0rd123"
set add_sudo "yes"
## Start the user creation utility
spawn ./create_user.sh
## Handle the username prompt
expect "Please enter new username: "
send "$username\r"
## Handle the password prompt
expect "Please enter password for $username: "
send "$password\r"
## Handle the password confirmation prompt
expect "Please confirm password: "
send "$password\r"
## Wait for the user creation confirmation
expect "User $username created successfully."
## Handle the sudo prompt
expect "Do you want to add this user to the sudo group? (yes/no): "
send "$add_sudo\r"
## If we chose to add to sudo, wait for confirmation
if {$add_sudo == "yes"} {
expect "User $username added to sudo group."
}
## Wait for completion
expect "User setup completed."
puts "\nUser creation automation completed successfully!"
Сохраните файл и сделайте его исполняемым:
chmod +x ~/project/create_user.exp
Запустите скрипт автоматизации создания пользователей:
cd ~/project
./create_user.exp
Пример вывода:
spawn ./create_user.sh
User creation utility
Please enter new username:
testuser
Please enter password for testuser:
Please confirm password:
Creating user testuser...
User testuser created successfully.
Do you want to add this user to the sudo group? (yes/no):
yes
Adding testuser to sudo group...
User testuser added to sudo group.
User setup completed.
User creation automation completed successfully!
Понимание практических скриптов expect
Практические скрипты, которые мы создали, демонстрируют несколько важных концепций для реальной автоматизации:
- Последовательное взаимодействие: Оба скрипта следуют определенной последовательности запросов и ответов.
- Мониторинг прогресса: Скрипт передачи файлов отслеживает прогресс и предоставляет удобные обновления для пользователя.
- Условная логика: Скрипт создания пользователей использует условную логику для обработки опции sudo.
- Настройка и очистка среды: Скрипт передачи файлов создает и очищает тестовые файлы.
Эти методы можно применять для автоматизации многих общих задач администрирования системы, таких как:
- Удаленное резервное копирование
- Установка программного обеспечения
- Настройка системы
- Пакетные операции
Освоив expect, вы можете автоматизировать сложные интерактивные процессы, которые в противном случае потребовали бы ручного вмешательства, экономя время и снижая вероятность человеческих ошибок.
Резюме
В этой лабораторной работе вы узнали, как использовать команду expect в Linux для автоматизации интерактивных приложений командной строки. Вы получили практический опыт работы с:
- Установкой и пониманием базового синтаксиса команды
expect - Созданием скриптов для автоматизации входа в систему SSH и обработки различных запросов аутентификации
- Обработкой нескольких запросов и ответов в скриптах
expect - Созданием практических скриптов автоматизации для общих задач администрирования системы
Команда expect — это мощный инструмент для системных администраторов и разработчиков, которым необходимо автоматизировать интерактивные процессы. Используя expect, вы можете исключить необходимость ручного вмешательства в повторяющиеся задачи, экономя время и снижая риск человеческих ошибок.
Некоторые ключевые выводы из этой лабораторной работы:
- Команда
expectиспользует модель шаблон-действие для взаимодействия с программами - Скрипты можно сделать более надежными, обрабатывая различные возможные запросы и условия ошибок
- Сложные взаимодействия можно автоматизировать с помощью условной логики и пользовательских процедур
- Практическая автоматизация может значительно повысить эффективность выполнения общих системных задач
С навыками, которые вы получили в этой лабораторной работе, вы теперь можете создавать свои собственные скрипты автоматизации для различных интерактивных приложений командной строки.



