Commande expect Linux avec exemples pratiques

LinuxBeginner
Pratiquer maintenant

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.

Linux Commands Cheat Sheet

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 :

  1. spawn : Démarre un processus avec lequel interagir
  2. expect : Attend une sortie spécifique du processus lancé
  3. send : Envoie une entrée au processus lancé
  4. 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éteur expect pour exécuter ce script.
  • set timeout 10 : Ceci définit un délai d'attente de 10 secondes pour toute commande expect qui suit.
  • spawn bash : Ceci démarre un nouveau processus shell bash avec lequel expect va 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 :

  1. Lancement de la connexion avec ssh username@hostname
  2. Acceptation de la clé d'hôte (si vous vous connectez pour la première fois)
  3. Saisie de votre mot de passe lorsque vous y êtes invité
  4. 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 :

  1. set timeout 10 : Définit un délai d'attente global de 10 secondes pour toutes les commandes expect.
  2. set password "mockpassword" : Stocke le mot de passe dans une variable.
  3. spawn ./mock_ssh_server.sh : Démarre notre script de serveur SSH simulé.
  4. expect "Are you sure you want to continue connecting (yes/no)? " : Attend l'invite de vérification de l'hôte.
  5. send "yes\r" : Envoie "yes" pour accepter la clé d'hôte.
  6. expect "Password: " : Attend l'invite de mot de passe.
  7. send "$password\r" : Envoie le mot de passe.
  8. expect "mockuser@mockserver:~$ " : Attend l'invite du shell.
  9. send "ls -la\r" : Envoie une commande pour lister les fichiers.
  10. expect "mockuser@mockserver:~$ " : Attend à nouveau l'invite du shell.
  11. send "exit\r" : Envoie la commande exit pour fermer la session.
  12. expect eof : Attend que le processus se termine.
  13. 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 :

  1. Gestion des erreurs : Il utilise un mécanisme de nouvelle tentative pour gérer les erreurs ou les réponses inattendues.
  2. Procédures : Il définit une procédure personnalisée appelée handle_error pour la gestion des erreurs réutilisable.
  3. Contrôle du flux : Il utilise une boucle while pour maintenir l'interaction jusqu'au succès ou au nombre maximal de tentatives.
  4. Plusieurs modèles expect : Il gère plusieurs modèles différents et prend les mesures appropriées pour chacun.
  5. Ordre des modèles : L'ordre des modèles dans le bloc expect est 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 :

  1. Interaction séquentielle : Les deux scripts suivent une séquence définie d'invites et de réponses.
  2. Surveillance de la progression : Le script de transfert de fichiers surveille la progression et fournit des mises à jour conviviales.
  3. Logique conditionnelle : Le script de création d'utilisateurs utilise une logique conditionnelle pour gérer l'option sudo.
  4. 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 expect utilise 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.

Linux Commands Cheat Sheet