Agence web » Actualités du digital » Automatisez les entrées dans les scripts Linux avec la commande expect –

Automatisez les entrées dans les scripts Linux avec la commande expect –

La commande Linux expect vous permet d’automatiser les interactions avec les scripts et les programmes. Vous pouvez envoyer n’importe quel type de réponse au script lorsqu’il attend une entrée de texte.

L’automatisation est synonyme d’efficacité

Lorsque vous administrez un ordinateur Linux ou un groupe d’ordinateurs, vous vous heurtez à de nombreuses tâches répétitives. La réponse évidente est d’écrire un script pour effectuer la majeure partie du travail à votre place. Le shell Bash, comme tous les shells modernes, fournit un langage de script riche et flexible.

Le script d’un travail long ou fastidieux vous donne la flexibilité d’exécuter cette tâche lorsque le bureau est fermé, ou dans les périodes les plus calmes d’une opération 24/7. Les scripts vous donnent également une répétabilité. Ils n’oublieront pas d’effectuer une étape, peu importe le nombre de fois qu’on leur demande d’effectuer les mêmes tâches ennuyeuses.

C’est bien, dans la mesure où cela disparaît. Mais si votre script nécessite une interaction de l’utilisateur ou s’il appelle un programme nécessitant une intervention humaine, que pouvez-vous faire? Vous ne voulez pas avoir à être présent lorsque le script s’exécute, ou si vous êtes présent, à regarder la fenêtre du terminal prêt à sauter et à appuyer sur quelques touches.

Linux a le yes commande, qui envoie un flux de caractères «y» ou toute autre chaîne spécifiée par l’utilisateur à la fenêtre du terminal. Si un programme attend une réponse à une question par oui ou par non, il sera alimenté de force par l’un des caractères «y». Il l’acceptera comme entrée et pourra continuer. Vous devez canaliser la sortie de yes dans le script.

yes | script.sh

Vous ne voudrez peut-être pas envoyer une réponse affirmative. Vous devez peut-être dire «non». Vous pouvez le faire aussi, en utilisant le yes commander. Vous pouvez envoyer n’importe quelle phrase, vous n’êtes pas limité aux réponses telles que « y », « Y », « Oui », « n », « N » ou « Non »

Vous devez peut-être envoyer un « r » pour réinstaller dans un « install/upgrade/reinstall [i/u/r]  » rapide.

yes r

le yes La commande ne peut pas faire face si elle doit fournir plus d’un type de réponse. Pour cette situation, nous devons utiliser expect .

Installation de la commande expect

Nous avons testé expect sur Ubuntu, Fedora et Manjaro. Le paquet n’était pas fourni avec ces distributions, il a donc dû être installé. Sur le type Ubuntu:

sudo apt install expect

Sur Fedora, la commande dont vous avez besoin est:

sudo dnf install expect

Sur Manjaro nous utilisons pacman:

sudo pacman -Sy expect

Comment attendre fonctionne

le expect La commande vous permet de gérer les deux extrémités de la conversation entre votre ensemble de réponses préparées et le programme ou le script auquel vous les enverrez. Pour ce faire, créez un script «attendu» qui surveille les invites dans le script principal et envoie la réponse appropriée pour chacune d’elles.

Supposons que vous ayez un script de sauvegarde qui demande un nom de répertoire source et un nom de répertoire cible. Il effectue ensuite une copie des fichiers du répertoire source dans le répertoire cible. Sans les bits qui effectuent la copie du fichier, votre script pourrait ressembler à ceci:

#!/bin/bash

echo "Directory to backup?"
read source_directory

echo "Backup location?"
read target_directory

echo
echo "Target directory:" $target_directory

Tout ce que ce script fait, c’est demander les chemins vers les deux répertoires. Il imprime le répertoire cible dans la fenêtre du terminal afin que nous puissions voir qu’il a reçu une réponse de expect et qu’il pouvait le lire correctement.

Pour fournir l’autre moitié de la conversation, nous créons un « script attendu ». Par convention, ceux-ci ont une extension «.exp». Cet exemple fonctionnera avec notre script «backup.sh».

#!/usr/bin/expect -f

set timeout -1

spawn ./backup.sh

expect "Directory to backup?r"
send -- "/home/dave/Documents/r"

expect "Backup location?r"
send -- "/media/dave/external/backupr"

expect eof

Cela montre les trois commandes principales dans les scripts expect, le spawn, expect, et send commandes.

La première chose à remarquer est que le shebang fait référence à expect, pas à bash. le -f (fichier) indique expect les réponses proviennent d’un fichier.

Nous désactivons efficacement les délais d’attente en les définissant sur l’infini avec -1.

le spawn La commande lance le script de sauvegarde.

Nous connaissons les deux questions que le script «backup.sh» nous posera. Pour chaque question, nous créons une ligne «attendue». Ceux-ci contiennent l’invite de texte qui sera envoyée à la fenêtre du terminal par le script «backup.sh». C’est quoi le expect programme surveillera. Lorsque expect voit l’invite, le texte dans le send est renvoyée au script «backup.sh».

le expect eof les lignes disent expect d’attendre la fin de fichier finale à la fin du traitement dans le script automatisé.

Rendez les deux scripts exécutables:

chmod +x backup.sh
chmod +x backup.exp

Et utilisez le script « backup.exp » pour lancer l’ensemble du processus.

./backup.exp

Vous pouvez voir les deux invites de «backup.sh» et les réponses de «backup.exp».

Ça va devenir Fiddly Fast

C’est formidable de voir deux scripts interagir comme celui-ci, avec les réponses automatisées envoyées par notre script expect et acceptées comme une véritable entrée par le script automatisé. Ceci est juste un exemple simple, bien sûr. Si vous essayez d’automatiser un processus de longue haleine – et ce sont eux que vous voudrez automatiser – vous risquez bientôt de vous enliser.

Le texte dans le expect les lignes doivent correspondre exactement aux invites du script que vous automatisez. Des fautes d’orthographe et une formulation incorrecte entraîneront le saut d’une invite et le processus automatisé s’arrêtera. Si vous êtes encore en train de développer ou de peaufiner le script que vous essayez d’automatiser, le libellé des invites et leur ordre dans le script sont susceptibles de changer. Les mises à niveau de scripts ou de programmes peuvent modifier, supprimer ou introduire des invites. Garder une trace des modifications et les répliquer dans votre script attendu devient fastidieux et sujet aux erreurs.

Le moyen le plus pratique de créer un script d’attente est d’utiliser autoexpect. Ceci est installé avec expect. On peut dire autoexpect pour surveiller notre interaction réelle avec un script ou un programme, et pour générer un fichier d’attente pour nous.

Il peut y avoir du rangement à faire dans le fichier expect généré, mais c’est beaucoup plus rapide que d’en écrire un à la main. Par exemple, si vous tapez quelque chose de manière erronée dans votre session lorsque autoexpect vous surveille, les frappes incorrectes ainsi que vos modifications et espacement arrière pour les corriger seront toutes capturées. Pour ranger cela, supprimez simplement cette section et tapez le texte correct.

Utilisation de l’attente automatique

Utilisant autoexpect est facile. Nous utilisons le -f (filename) pour lui indiquer le nom du fichier attendu qu’il doit créer, ainsi que le programme ou le script que nous voulons qu’il exécute. Les invites du processus et nos réponses sont enregistrées et envoyées au fichier attendu. En guise de gentillesse, autoexpect rend le fichier expect exécutable pour nous.

Disons que nous utilisons fréquemment rsync pour envoyer des fichiers d’un ordinateur vers un répertoire sur un autre ordinateur via le réseau. Nous utiliserons autoexpect pour créer un fichier d’attente de ce processus.

Notre ligne de commande ressemble à ceci. La première commande est autoexpect suivi du -f drapeau et le nom du fichier attendu que nous voulons créer. Dans ce cas, il s’agit de « send-pics.exp. »

Le reste de la commande est le régulier rsync commander. Parce que rsync utilise le SSH pour se connecter à distance à l’ordinateur cible, nous devrons fournir le mot de passe du compte utilisateur «dave» sur l’ordinateur cible.

autoexpect -f send-pics.exp rsync -rasv ~/Pictures/raw/ dave@nostromo.local:/home/dave/raw/

Quand nous exécutons cette commande rsync est lancé et on nous demande le mot de passe du compte de l’utilisateur dave sur l’ordinateur distant. Une fois que c’est entré, certains fichiers sont envoyés à l’ordinateur distant, rsync rompt la connexion et le processus se termine.

On nous dit que le fichier «send-pics.exp» a été créé. Nous allons jeter un coup d’oeil:

ls -l send-pics.exp

Il a bien été créé et il est exécutable. Nous pouvons l’exécuter en l’appelant par son nom:

./send-pics.exp

Cette fois, le processus se déroule sans aucune interaction humaine. Tous les nouveaux fichiers depuis le dernier transfert sont envoyés à la machine distante.

Ceci est un très petit exemple de script. Cela ne permet guère d’économiser aucun effort par rapport à l’exécution du rsync commande à la main. Bien que ce soit vrai, cela illustre le fait que vous pouvez contrôler des programmes ainsi que des scripts, et vous pouvez appliquer les principes vus ici à des scripts ou des processus de n’importe quelle longueur.

Accrochez-vous, mon mot de passe!

Vous devez être conscient que tous les mots de passe – ou toute autre information sensible – recueillis au cours d’une autoexpect session sont stockés en texte brut dans le script expect généré. Les mots de passe ne doivent jamais être écrits en texte brut. Pour les connexions SSH, une meilleure solution consiste à utiliser des clés SSH et à avoir un schéma d’authentification sans mot de passe.

Évidemment, cela n’aidera pas si vous n’utilisez pas SSH.

Vous pouvez modifier votre script attendu et changer la ligne qui traite de votre mot de passe en:

interact ++ return

Lorsque le script atteint cette ligne, il attend votre saisie, vous permettant de saisir votre mot de passe. Le contrôle revient ensuite au script attendu une fois que vous avez fourni votre mot de passe.

./send-pics.exp

Mais cela pose un problème différent. Cela signifie que votre script ne peut plus s’exécuter sans surveillance. Si vous lancez toujours manuellement votre script, cela n’a probablement pas d’importance, surtout si la demande de mot de passe se produit juste au début du script. Vous pouvez lancer le script, entrer votre mot de passe, puis le laisser se débrouiller tout seul.

Une autre façon de résoudre le problème consiste à:

  • Modifiez les autorisations de fichier sur votre script attendu à l’aide de chown à 740, -rwxr-x---.
  • Utiliser chmod pour remplacer le propriétaire du groupe du script attendu par un groupe de confiance.
  • Créez un script régulier qui lance votre script attendu. Définissez ce fichier pour qu’il appartienne également au groupe de confiance. Définissez les autorisations à ce sujet sur 2751, -rwxr-s--x.
  • Cela crée un script de lancement que tout le monde peut lire et exécuter, qui est dans le même groupe de confiance que le script attendu, et avec son setgid jeu de bits. Indépendamment de qui exécute ce script, son groupe effectif sera le groupe de confiance et non le groupe de la personne exécutant le script. Ainsi, ce script pourra toujours lancer le script attendu.
  • Pendant ce temps, le script expect contenant le mot de passe est inaccessible à quiconque sauf à vous.

Vous pouvez vous attendre à de grandes choses

Il y en a assez ici pour vous faire avancer, mais il y a beaucoup plus à faire expect que les domaines que nous avons couverts. le expect la page de manuel fait plus de 1700 lignes!

Pour des tâches telles que les installations automatisées, les sauvegardes planifiées ou les déploiements répétitifs, attendez-vous à transformer votre flux de travail.

★★★★★