Table des matières
Résumé
A la fin de ce chapitre vous serez capable de:
Ecrire un script simple
Définir le type de Shell qui doit exécuter le script
Ajouter des commentaires
Changer les permissions du script
Exécuter et débugger un script
Un script Shell est une séquence de commandes dont vous avez un usage répété. Cette séquence est en principe exécutée en entrant le nom du script sur la ligne de commande. Alternativement, vous pouvez utiliser des scripts pour automatiser des tâches via l'outil cron. Un autre usage des scripts est celui fait par la procédure de démarrage et d'arrêt d'UNIX où les opérations des services et démons sont définies dans des scripts "init".
Pour créer un script Shell, ouvrez un nouveau fichier vide dans un éditeur. N'importe lequel fera l'affaire: vim, emacs, gedit, dtpad, etc.. Vous pourriez cependant vouloir employer un éditeur plus sophistiqué comme vim ou emacs, parce qu'ils peuvent être configurés pour reconnaître la syntaxe Shell et Bash et cela peut être d'une grande aide pour éviter les erreurs les plus fréquentes des débutants telles que les oublis de parenthèses et de points-virgules.
Entrez des commandes UNIX dans ce nouveau fichier, comme vous le feriez sur la ligne de commande. Ainsi que nous l'avons vu dans le chapitre précédent (see Section 3, « L'exécution de commandes »), les commandes peuvent être des fonctions Shell, des commandes intégrées, des commandes UNIX et le nom d'un autre script.
Nommez votre script significativement de sorte à donner une indication sur ce qu'il fait. Assurez vous que ce nom ne soit pas en conflit avec une commande existante(NdT: �itez 'test' qui est une commande). Afin de s'assurer qu'aucun conflit de nom ne survienne, le nom de script finit souvent par .sh. Même ainsi il se pourrait qu'un autre script de votre système porte le nom que vous avez choisit. Contrôlez avec which, whereis et autres commandes cherchant des informations sur les programmes et les fichiers:
which -a script_name
whereis script_name
locate script_name
Dans cet exemple nous utilisons l'intégrée Bash echo pour informer l'utilisateur de ce qui va se produire avant d'exécuter les commandes qui vont produire le résultat. Il est fortement conseillé d'informer l'utilisateur de ce que le script va faire, pour l'empêcher de devenir inquiet parce que le script semble ne rien faire. Nous reviendrons sur le sujet de l'avertissement à l'utilisateur au Chapitre 8, Ecrire des scripts interactifs.
Ecrivez ce script. Il peut être une bonne idée de créer un répertoire ~/scripts pour ranger vos scripts. Ajoutez le répertoire au contenu de la variable PATH:
export PATH="$PATH:~/scripts"
Si vous êtes tout nouveau avec Bash, utilisez un éditeur de texte qui emploie différentes couleurs pour les différentes constructions syntaxiques. Le code de couleur est une fonction de vim, gvim, (x)emacs, kwrite et de beaucoup d'autres éditeurs; se référer à la documentation de votre éditeur.
L'invite varie au long de ce guide selon l'humeur de l'auteur. Ce qui ressemble plus à la vie réelle que l'invite classique $. La seule convention que nous avons gardé est que l'invite de root finit par #.
Le script doit avoir les permissions d'exécution attribuées aux bonnes personnes pour qu'il soit exécutable. Quand vous attribuez des permissions, vérifiez que vous obtenez le résultat escompté. Une fois fait, le script peut être lancé comme toute autre commande:
willy:~/scripts>chmodu+xscript1.shwilly:~/scripts>ls-lscript1.sh-rwxrw-r-- 1 willy willy 456 Dec 24 17:11 script1.shwilly:~>script1.sh Le script démarre. Salut, willy! Je vais afficher une liste des utilisateurs connectés: 3:38pm up 18 days, 5:37, 4 users, load average: 0.12, 0.22, 0.15 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root tty2 - Sat 2pm 4:25m 0.24s 0.05s -bash willy :0 - Sat 2pm ? 0.00s ? - willy pts/3 - Sat 2pm 3:33m 36.39s 36.39s BitchX willy ir willy pts/2 - Sat 2pm 3:33m 0.13s 0.06s /usr/bin/screen Je définis 2 variables, maintenant. Ceci est une chaîne: noir Et ceci est un nombre: 9 Je vous rends la main, maintenant.willy:~/scripts>echo$COLOURwilly:~/scripts>echo$VALUEwilly:~/scripts>
C'est la façon la plus courante d'exécuter un script. C'est préférable d'exécuter le script comme ça dans un sous-Shell. Les variables, fonctions et alias créés dans le sous-Shell sont seulement connus dans la session Bash de ce sous-Shell. Quand le sous-Shell finit et que le parent reprend le contrôle, tout est réinitialisé et les changements fait dans l'environnement du Shell par le script sont oubliés.
Si vous ne mettez pas le répertoire de scripts dans votre PATH, et si . (le répertoire courant) n'est pas dans le PATH non plus, vous pouvez lancer le script comme ceci:
./script_name.sh
Un script peut aussi être explicitement exécuté par un Shell particulier, mais généralement on ne fait ça que pour obtenir un comportement spécial, comme vérifier que le script tourne avec un autre Shell ou afficher une trace pour debugger.
rbash script_name.sh
sh script_name.sh
bash -x script_name.sh
Le Shell spécifié démarrera en tant que sous-Shell de votre Shell actif et exécutera le script. On le fait quand on veut que le script démarre avec des options ou des conditions spécifiques qui ne sont pas indiquées dans le script.
Si on ne veut pas lancer un nouveau Shell mais exécuter le script dans le Shell actif, on le source:
source script_name.sh
L'intégrée Bash source est un synonyme de la commande Bourne shell . (dot).
Le script n'a pas besoin de permission d'exécution dans ce cas. Les commandes sont exécutées dans l'environnement du Shell actif, par conséquent tout changement restera tel quel quand le script aura terminé:
willy:~/scripts>sourcescript1.sh--output ommitted--willy:~/scripts>echo$VALUE9willy:~/scripts>
Quand vous lancez un script dans un sous-Shell, vous devriez définir quel Shell l'exécutera. Le type de Shell pour lequel vous avez écrit le script peut ne pas être celui par défaut de votre système, alors les commandes peuvent ne pas être interprétées par un Shell inadéquat.
La première ligne du script définit le Shell à lancer. Les 2 premiers caractères de la première ligne devraient être #!, puis suit le chemin vers le Shell qui doit interpréter les commandes qui suivent. Les lignes blanches sont aussi prises en compte, donc ne commencez pas votre script par une ligne vide.
Dans ce guide, tous les scripts commenceront par la ligne
#!/bin/bash
Comme indiqué auparavant, ceci implique que le programme Bash doit se trouver dans /bin.
Vous devriez vous rappeler que vous ne serez peut-être pas la seule personne à lire votre code. Beaucoup d'utilisateurs et d'administrateurs système lancent des scripts qui ont été écrits par d'autres. Si ils veulent comprendre comment vous avez fait, les commentaires sont là pour éclairer.
Les commentaires vous font aussi la vie plus facile. Par exemple vous avez lu beaucoup de pages man pour obtenir de certaines commandes de votre script un résultat donné. Vous ne vous souviendrez plus de ce qu'il fait après quelques semaines, à moins d'avoir commenté ce que vous avez fait, comment et pourquoi.
Prenez en exemple script1.sh et copiez le sur commented-script1.sh, que vous éditez de sorte que les commentaires réflètent ce que le script fait. Tout ce qui apparaît après le # sur une ligne est ignoré par le Shell et n'apparaît qu'à l'édition.
#!/bin/bash # Ce script efface le terminal, affiche un message d'accueil et donne des informations # sur les utilisateurs connectés. Les 2 exemples de variables sont définis et affichés. clear # efface le terminal echo "Le script démarre." echo "Salut, $USER!" # le signe dollar est employé pour obtenir le contenu d'une variable echo echo "Je vais maintenant vous afficher une liste des utilisateurs connectés:" echo w # montre qui est connecté echo # et ce qu'ils font echo "Je définis 2 variables maintenant." COLOUR="noir" # définit une variable locale Shell VALUE="9" # définit une variable locale Shell echo "Ceci est une chaîne: $COLOUR" # affiche le contenu de la variable echo "Et ceci est un nombre: $VALUE" # affiche le contenu de la variable echo echo "Je vous redonne la main maintenant." echo
Dans un script correct, les premières lignes sont habituellement des commentaires sur son but. Puis chaque portion importante de code devrait être commentée autant que la clareté le demande. Les scripts d'init Linux, par exemple, dans le répertoire init.d sont généralement bien documentés puisque ils doivent être lisibles et éditables par quiconque utilise Linux.
Quand le résultat n'est pas celui attendu, vous devez déterminer ce qui a causé l'erreur. Bash fournit des possibilités de débuggage importantes. La plus commune est de lancer le sous-Shell avec l'option -x ce qui fait s'exécuter le script en mode débug. Une trace de chaque commande avec ses arguments est affichée sur la sortie standard après que la commande ait été interprétée mais avant son exécution.
Voici le script commented-script1.sh lancé en mode débug. Notez que les commentaires ne sont pas visibles dans la sortie du script.
willy:~/scripts>bash-xscript1.sh+ clear + echo 'Le script démarre.' Le script démarre. + echo 'Salut, willy!' Salut, willy! + echo + echo 'Je vais maintenant vous afficher une liste des utilisateurs connectés:' Je vais maintenant vous afficher une liste des utilisateurs connectés: + echo + w 4:50pm up 18 days, 6:49, 4 users, load average: 0.58, 0.62, 0.40 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root tty2 - Sat 2pm 5:36m 0.24s 0.05s -bash willy :0 - Sat 2pm ? 0.00s ? - willy pts/3 - Sat 2pm 43:13 36.82s 36.82s BitchX willy ir willy pts/2 - Sat 2pm 43:13 0.13s 0.06s /usr/bin/screen + echo + echo 'Je définis 2 variables maintenant.' Je définis 2 variables maintenant. + COLOUR=noir + VALUE=9 + echo 'Ceci est une chaîne: ' Ceci est une chaîne: + echo 'Et ceci est un nombre: ' Et ceci est un nombre: + echo + echo 'Je vous redonne la main maintenant.' Je vous redonne la main maintenant. + echo
Il y a maintenant un débugger complet pour Bash, disponible sur SourceForge. Cependant, cela nécessite une version modifiée de bash-2.05. Cette fonctionnalité devrait être disponible dans la version bash-3.0.
En utilisant l'intégrée Bash set vous pouvez faire exécuter en mode normal les portions de code dont vous pensez être sûr, et faire afficher les informations pour celles pour lesquelles vous avez un doute. Disons que nous ne sommes pas sûr de ce que la commande w fera dans l'exemple commented-script1.sh, alors nous pouvons l'entourer dans le script comme ceci:
set -x # active le mode débug w set +x # stoppe le mode débug
La sortie affiche alors ceci:
willy: ~/scripts>script1.sh Le script démarre. Salut, willy! Je vais maintenant vous afficher une liste des utilisateurs connectés: + w 5:00pm up 18 days, 7:00, 4 users, load average: 0.79, 0.39, 0.33 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root tty2 - Sat 2pm 5:47m 0.24s 0.05s -bash willy :0 - Sat 2pm ? 0.00s ? - willy pts/3 - Sat 2pm 54:02 36.88s 36.88s BitchX willyke willy pts/2 - Sat 2pm 54:02 0.13s 0.06s /usr/bin/screen + set +x Je définis 2 variables maintenant. Ceci est une chaîne: Et ceci est un nombre: Je vous redonne la main maintenant.willy: ~/scripts>
On peut basculer du mode activé à désactivé autant de fois que l'on veut dans le script.
Le tableau ci-dessous donne un aperçu d'autres options utiles de Bash:
Tableau 2.1. Aperçu des options de débug
| Syntaxe abrégée | Syntaxe longue | Effet |
|---|---|---|
| set -f | set -o noglob | Désactive la génération de noms de fichiers à partir des métacaractères (globbing). |
| set -v | set -o verbose | Affiche les lignes fournies au Shell telle qu'elles ont été lues. |
| set -x | set -o xtrace | Affiche la trace des commandes avant leur exécution. |
Le signe - est utilisé pour activer une option Shell et le + pour la désactiver. Ne vous faites pas avoir!
Dans l'exemple qui suit, nous montrons l'usage de ces options depuis la ligne de commande:
willy:~/scripts>set-vwilly:~/scripts>ls ls commented-scripts.sh script1.shwilly:~/scripts>set+vset +vwilly:~/scripts>ls*commented-scripts.sh script1.shwilly:~/scripts>set-fwilly:~/scripts>ls*ls: *: No such file or directorywilly:~/scripts>touch*willy:~/scripts>ls * commented-scripts.sh script1.shwilly:~/scripts>rm*willy:~/scripts>ls commented-scripts.sh script1.sh
De façon alternative, ces modes peuvent être indiqués dans le script lui-même, en ajoutant l'option voulue sur la première ligne de déclaration du Shell. Les options peuvent être combinées, comme c'est généralement le cas pour les commandes UNIX:
#!/bin/bash -xv
Une fois que vous avez trouvé la portion de code erronée, vous pouvez ajouter l'instruction echo devant chaque commande dont vous n'êtes pas sûr, afin de voir précisément où et pourquoi ça ne tourne pas rond. Dans le script d'exemple commented-script1.sh cela pourrait être fait comme ceci, toujours en supposant que l'affichage des utilisateurs n'est pas correct.
echo "debug message: avant exécution de la commande w"; w
Dans des scripts plus élaborés echo peut être inséré pour faire afficher le contenu de variables à différentes étapes du script, afin de détecter les erreurs:
echo "Variable VARNAME a la valeur $VARNAME."
Un script Shell est une série réutilisable de commandes saisies dans un fichier de texte exécutable. Tout type d'éditeur de texte peut être utilisé pour écrire des scripts.
Un script commence par#! suivi par le chemin vers le Shell qui exécutera les commandes qui viennent après. Les commentaires sont ajoutés au script pour vos propres besoins ultérieurs, et aussi pour le rendre compréhensible par les autres. Mieux vaut avoir trop d'explications que pas assez.
Corriger un script peut être fait grâce aux options Shell de débug. Ces options peuvent être utilisées sur une partie ou sur la totalité du script. Ajouter des commandes echo a des endroits judicieusement choisis est aussi un bon moyen de traquer l'erreur.
Cet exercice vous aidera à créer votre premier script.
Ecrire un script au moyen de votre éditeur favori. Le script devrait afficher le chemin de votre répertoire utilisateur et le type de terminal que vous utilisez. De plus il montrera tous les services lancés par le niveau d'exécution 3 de votre système. (astuce: employez HOME, TERM et ls /etc/rc3.d/S*)
Ajoutez des commentaires.
Ajoutez des informations à destination de l'utilisateur.
Changer les permissions de sorte que vous puissiez le lancer.
Exécuter le script en mode normal puis en mode débug. Il doit s'exécuter sans erreurs.
Faites que le script fasse une erreur: voyez ce qui arrive si la première ligne n'est pas correcte ou si vous libellez mal une commande ou une variable - par exemple déclarez une variable par un nom en majuscule et référencez-la avec le nom en minuscule. Voyez ce que les commentaires de débug affichent dans ce cas.