Introduction
Dans ce laboratoire, vous apprendrez à utiliser la commande Linux expect pour automatiser les applications interactives en ligne de commande. La commande expect est un outil d'automatisation puissant qui permet aux scripts d'interagir avec des programmes nécessitant une saisie utilisateur, tels que SSH, FTP et d'autres programmes interactifs.
À la fin de ce laboratoire, vous serez capable de :
- Comprendre le but et la syntaxe de base de la commande
expect - Créer des scripts pour automatiser les connexions SSH
- Gérer diverses invites et réponses dans vos scripts
expect
La commande expect peut réduire considérablement l'intervention manuelle pour les tâches répétitives, rendant l'administration système et les tâches de routine plus efficaces. Vous commencerez par installer et explorer la syntaxe de base d'expect, puis vous progresserez vers la création de scripts pour automatiser les connexions SSH et gérer diverses invites interactives.
Comprendre la commande expect et sa syntaxe de base
La commande expect sous Linux vous permet d'automatiser les programmes interactifs en ligne de commande qui nécessitent normalement une saisie utilisateur. Ceci est particulièrement utile pour des tâches telles que les connexions automatisées, les transferts de fichiers, ou toute situation où un programme invite à une saisie.
Installation d'expect
Tout d'abord, vérifions que le paquet expect est installé sur notre système. Ouvrez votre terminal et exécutez :
which expect
Si expect est déjà installé, vous verrez son chemin (comme /usr/bin/expect). Sinon, vous devrez l'installer :
sudo apt-get update
sudo apt-get install -y expect
Comprendre la syntaxe de base d'expect
La commande expect utilise un langage de script basé sur Tcl (Tool Command Language). La structure de base d'un script expect comprend les commandes suivantes :
spawn: Démarre un processus avec lequel interagirexpect: Attend une sortie spécifique du processus lancésend: Envoie une entrée au processus lancéset timeout: Définit le temps d'attente pour la sortie attendue
Créons un script expect simple pour démontrer ces concepts. Ouvrez un éditeur de texte et créez un fichier nommé hello.exp dans votre répertoire de projet :
cd ~/project
nano hello.exp
Tapez le contenu suivant dans le fichier :
#!/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
Enregistrez le fichier en appuyant sur Ctrl+O, puis sur Entrée, et quittez nano avec Ctrl+X.
Rendez le script exécutable :
chmod +x ~/project/hello.exp
Maintenant, exécutez le script :
~/project/hello.exp
Vous devriez voir une sortie similaire à celle-ci :
spawn bash
$ echo Hello from expect
Hello from expect
$ exit
exit
Comprendre chaque ligne du script
Laissez-moi vous expliquer ce que fait chaque ligne du script :
#!/usr/bin/expect -f: Il s'agit d'une ligne shebang qui indique au système d'utiliser l'interpréteurexpectpour exécuter ce script.set timeout 10: Ceci définit un délai d'attente de 10 secondes pour toute commandeexpectqui suit.spawn bash: Ceci démarre un nouveau processus shell bash avec lequelexpectva interagir.expect "$ ": Ceci attend l'apparition de l'invite bash.send "echo Hello from expect\r": Ceci envoie la commande au shell bash. Notez le\rà la fin, qui simule la pression sur Entrée.expect "$ ": Ceci attend à nouveau l'invite bash, après que la commande a été exécutée.send "exit\r": Ceci envoie la commande exit pour fermer le shell bash.expect eof: Ceci attend que le processus lancé se termine.
Cet exemple simple démontre la fonctionnalité principale d'expect. Dans les prochaines étapes, nous utiliserons ces concepts pour créer des scripts plus pratiques.
Création d'un script de connexion SSH simulé avec expect
Dans cette étape, nous allons créer un script expect qui simule un processus de connexion SSH. Puisque nous ne pouvons pas effectuer une véritable connexion SSH dans cet environnement, nous allons créer un script simulé qui démontre les principes.
Comprendre le flux d'authentification SSH
Lors de la connexion à un serveur distant via SSH, l'interaction typique implique :
- Lancement de la connexion avec
ssh username@hostname - Acceptation de la clé d'hôte (si vous vous connectez pour la première fois)
- Saisie de votre mot de passe lorsque vous y êtes invité
- Accès au shell distant
Créons un environnement SSH simulé pour démontrer comment expect peut automatiser ce processus.
Création d'un script de serveur SSH simulé
Tout d'abord, créons un script qui simule un serveur SSH demandant un mot de passe :
cd ~/project
nano mock_ssh_server.sh
Entrez le contenu suivant :
#!/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
Enregistrez le fichier et rendez-le exécutable :
chmod +x ~/project/mock_ssh_server.sh
Ce script simule :
- L'invite de vérification de l'hôte SSH
- L'invite de mot de passe
- Un shell simple qui répond aux commandes
Création d'un script expect pour automatiser la connexion
Maintenant, créons un script expect qui automatise l'interaction avec notre serveur SSH simulé :
cd ~/project
nano ssh_login.exp
Entrez le contenu suivant :
#!/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!"
Enregistrez le fichier et rendez-le exécutable :
chmod +x ~/project/ssh_login.exp
Exécution du script de connexion automatisée
Maintenant, exécutons notre script expect pour automatiser l'interaction avec le serveur SSH simulé :
cd ~/project
./ssh_login.exp
Vous devriez voir une sortie similaire à celle-ci :
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!
Explication du script
Laissez-moi vous expliquer ce que fait chaque partie de notre script expect :
set timeout 10: Définit un délai d'attente global de 10 secondes pour toutes les commandesexpect.set password "mockpassword": Stocke le mot de passe dans une variable.spawn ./mock_ssh_server.sh: Démarre notre script de serveur SSH simulé.expect "Are you sure you want to continue connecting (yes/no)? ": Attend l'invite de vérification de l'hôte.send "yes\r": Envoie "yes" pour accepter la clé d'hôte.expect "Password: ": Attend l'invite de mot de passe.send "$password\r": Envoie le mot de passe.expect "mockuser@mockserver:~$ ": Attend l'invite du shell.send "ls -la\r": Envoie une commande pour lister les fichiers.expect "mockuser@mockserver:~$ ": Attend à nouveau l'invite du shell.send "exit\r": Envoie la commande exit pour fermer la session.expect eof: Attend que le processus se termine.puts "\nSSH login automation completed successfully!": Affiche un message de succès.
Cet exemple démontre comment expect peut être utilisé pour automatiser l'ensemble du processus de connexion SSH, de l'acceptation de la clé d'hôte à l'exécution de commandes sur le serveur distant et à la sortie en toute sécurité.
Gestion de plusieurs invites et réponses avec expect
Dans des scénarios réels, les programmes interactifs présentent souvent plusieurs invites et peuvent nécessiter des réponses différentes en fonction de conditions différentes. Dans cette étape, nous allons apprendre à gérer plusieurs invites et réponses conditionnelles dans les scripts expect.
Comprendre les blocs expect conditionnels
La commande expect peut être utilisée avec une structure de bloc pattern-action pour gérer différentes invites possibles :
expect {
"pattern1" { actions for pattern1 }
"pattern2" { actions for pattern2 }
timeout { actions for timeout }
eof { actions for end of file }
}
Cette structure permet à votre script de répondre différemment en fonction de la sortie qu'il reçoit.
Création d'un script de gestion multi-invites
Créons un script qui simule un programme avec plusieurs invites :
cd ~/project
nano multi_prompt.sh
Entrez le contenu suivant :
#!/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
Enregistrez le fichier et rendez-le exécutable :
chmod +x ~/project/multi_prompt.sh
Maintenant, créons un script expect pour interagir avec ce programme et gérer toutes les invites possibles :
cd ~/project
nano handle_prompts.exp
Entrez le contenu suivant :
#!/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!"
Enregistrez le fichier et rendez-le exécutable :
chmod +x ~/project/handle_prompts.exp
Exécution du script de gestion multi-invites
Maintenant, exécutons notre script expect pour interagir avec le programme multi-invites :
cd ~/project
./handle_prompts.exp
Chaque fois que vous exécutez ce script, il sélectionnera aléatoirement l'une des options et décidera aléatoirement de continuer ou de quitter. Voici un exemple de sortie :
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!
Création d'un script expect plus avancé
Créons maintenant un script plus avancé qui peut gérer les invites et les erreurs inattendues :
cd ~/project
nano advanced_expect.exp
Entrez le contenu suivant :
#!/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
Enregistrez le fichier et rendez-le exécutable :
chmod +x ~/project/advanced_expect.exp
Exécutez le script avancé :
cd ~/project
./advanced_expect.exp
Exemple de sortie :
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!
Comprendre le script avancé
Ce script avancé démontre plusieurs techniques expect importantes :
- Gestion des erreurs : Il utilise un mécanisme de nouvelle tentative pour gérer les erreurs ou les réponses inattendues.
- Procédures : Il définit une procédure personnalisée appelée
handle_errorpour la gestion des erreurs réutilisable. - Contrôle du flux : Il utilise une boucle while pour maintenir l'interaction jusqu'au succès ou au nombre maximal de tentatives.
- Plusieurs modèles expect : Il gère plusieurs modèles différents et prend les mesures appropriées pour chacun.
- Ordre des modèles : L'ordre des modèles dans le bloc
expectest important - les modèles plus spécifiques doivent venir avant les modèles plus généraux.
Ces techniques peuvent être appliquées pour automatiser des programmes interactifs complexes où le flux peut varier ou des erreurs peuvent survenir.
Création de scripts expect pratiques pour les tâches courantes
Dans cette étape, nous allons créer des scripts expect pratiques pour les tâches courantes que les administrateurs système doivent souvent automatiser. Nous nous concentrerons sur les opérations de fichiers, les interactions utilisateur et la surveillance du système.
Automatisation du transfert de fichiers avec expect
Créons un script expect qui automatise le transfert d'un fichier à l'aide de la commande scp. Puisque nous ne pouvons pas effectuer un véritable transfert de fichiers dans cet environnement, nous allons le simuler :
cd ~/project
nano file_transfer.sh
Entrez le contenu suivant pour simuler un transfert de fichiers de type 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
Enregistrez le fichier et rendez-le exécutable :
chmod +x ~/project/file_transfer.sh
Maintenant, créons un script expect pour automatiser ce transfert de fichiers :
cd ~/project
nano file_transfer.exp
Entrez le contenu suivant :
#!/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
Enregistrez le fichier et rendez-le exécutable :
chmod +x ~/project/file_transfer.exp
Exécutez le script d'automatisation du transfert de fichiers :
cd ~/project
./file_transfer.exp
Exemple de sortie :
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
Automatisation de la création d'utilisateurs avec expect
Maintenant, créons un script expect qui automatise la création d'utilisateurs. Encore une fois, nous allons simuler ce processus :
cd ~/project
nano create_user.sh
Entrez le contenu suivant :
#!/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."
Enregistrez le fichier et rendez-le exécutable :
chmod +x ~/project/create_user.sh
Maintenant, créons un script expect pour automatiser la création d'utilisateurs :
cd ~/project
nano create_user.exp
Entrez le contenu suivant :
#!/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!"
Enregistrez le fichier et rendez-le exécutable :
chmod +x ~/project/create_user.exp
Exécutez le script d'automatisation de la création d'utilisateurs :
cd ~/project
./create_user.exp
Exemple de sortie :
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!
Comprendre les scripts expect pratiques
Les scripts pratiques que nous avons créés démontrent plusieurs concepts importants pour l'automatisation en conditions réelles :
- Interaction séquentielle : Les deux scripts suivent une séquence définie d'invites et de réponses.
- Surveillance de la progression : Le script de transfert de fichiers surveille la progression et fournit des mises à jour conviviales.
- Logique conditionnelle : Le script de création d'utilisateurs utilise une logique conditionnelle pour gérer l'option sudo.
- Configuration et nettoyage de l'environnement : Le script de transfert de fichiers crée et nettoie les fichiers de test.
Ces techniques peuvent être appliquées pour automatiser de nombreuses tâches courantes d'administration système, telles que :
- Sauvegardes à distance
- Installations de logiciels
- Configuration du système
- Opérations par lots
En maîtrisant expect, vous pouvez automatiser des processus interactifs complexes qui nécessiteraient autrement une intervention manuelle, ce qui permet de gagner du temps et de réduire le risque d'erreurs humaines.
Résumé
Dans ce laboratoire, vous avez appris à utiliser la commande expect sous Linux pour automatiser les applications interactives en ligne de commande. Vous avez acquis une expérience pratique avec :
- L'installation et la compréhension de la syntaxe de base de la commande
expect - La création de scripts pour automatiser les connexions SSH et gérer diverses invites d'authentification
- La gestion de plusieurs invites et réponses dans les scripts
expect - La création de scripts d'automatisation pratiques pour les tâches courantes d'administration système
La commande expect est un outil puissant pour les administrateurs système et les développeurs qui ont besoin d'automatiser des processus interactifs. En utilisant expect, vous pouvez éliminer le besoin d'une intervention manuelle dans les tâches répétitives, ce qui permet de gagner du temps et de réduire le risque d'erreurs humaines.
Quelques points clés à retenir de ce laboratoire :
- La commande
expectutilise un modèle pattern-action (motif-action) pour interagir avec les programmes - Les scripts peuvent être rendus plus robustes en gérant diverses invites possibles et conditions d'erreur
- Des interactions complexes peuvent être automatisées à l'aide d'une logique conditionnelle et de procédures personnalisées
- L'automatisation pratique peut améliorer considérablement l'efficacité des tâches système courantes
Grâce aux compétences que vous avez acquises dans ce laboratoire, vous pouvez désormais créer vos propres scripts d'automatisation pour diverses applications interactives en ligne de commande.



