Les scripts sont des programmes en langages interprétés : ce sont des fichiers écrit dans des langages qui sont convertit en instructions directement exécutables par la machine au moment de son exécution. On appel ces langages, langages de script.
Ces langages sont parfois interprétés par un shell (nous allons définir ce qu'est un shell par la suite), ce sont des langages qui permet de manipuler les fonctionnalités du système. On associe, d'ailleurs, souvent le langage de script au shell qui l'interprète. C'est le cas de Bash que nous allons traiter dans ce cours.
Les shells qu'est ce que c'est ?
Les Shells sont des interfaces qui servent à communiquer avec le système, elles sont le plus généralement présents dans les systèmes de type Unix. Pour les systèmes Unix, il s'agit d'un interpréteur de commande en mode texte.
Il existe plusieurs shell, sur les systèmes de type Unix, dont les plus connus sont les suivants :
- Bash (le Bourne Again SHell). C'est le shell le plus utilisé aujourd'hui.
-
sh (le bourne SHell). Ce shell fut le premier présent dans les systèmes Unix et est à l'origine de tout les autres.
- Ksh (Korn SHell).
- Csh (le C SHell) dont la syntaxe est inspirée du langage C).
- Tcsh (le Tenex C Shell). C'est une évolution du Csh.
- Zsh (le Z Shell). C'est un shell récent basé sur Bash, Ksh et Tcsh.
Le Bash est sans doute le shell le plus utilisé aujourd'hui sur les systèmes de type Unix (en particulier pour la plupart des distributions Linux et la génération des Mac OS X) et c'est sur lui que portera ce tutoriel. Vous pouvez néanmoins définir un autre shell par défaut dans votre terminale ou tout simplement en l'utilisant de manière passagère (pour cela il suffit de l'appeler en console, par exemple ksh pour appeler Ksh).
Le shell utilisé par défaut par votre terminal n'influe pas sur l'usage d'un autre shell dans des scripts. Par contre il faut vérifier que le shell que vous souhaitez utilisé dans votre script soit bien présent dans le répertoire /bin. Sinon vous pourrez toujours l'installer.
Quelques informations supplémentaires sur Bash ?
Bash signifie Bourne Again SHell. C'est un jeu de mot avec le Bourne shell, le shell original d'Unix sur lequel Bash est majoritairement basé, et de l'anglais born again (né de nouveau ou encore réincarné).
Le Bourne Again Shell est le shell du projet GNU basé principalement sur le Bourne Shell, mais lui apportant de nombreuses améliorations provenant d'autres types de shells, notamment du Korn Shell et du C shell. qui signifie
Les scripts Bash sont donc des fichiers texte qui contiennent des commandes shell et des instructions de contrôle de type if, while, ... Ils sont directement interprétés par le shell en question et permettent d'automatiser les tâches en console habituelles qui sont souvent des tâches d'administration.
De quoi as t'on besoin pour programmer en Bash ?
Pour développer en Bash, un éditeur de texte quelconque comme Gedit ou Kate suffit. Vous pouvez également (et c'est souvent utile lorsque que vous faites du scripting sans interface graphique) utiliser un éditeur en mode console tel que Nano (pour les utilisateurs débutants), Vim ou Emacs (pour les utilisateurs avertis).
Il faut aussi savoir que connaître les syntaxes des différentes instructions en Bash ne suffit pas à la réalisation d'un script. En effet, il faut connaître un minimum de commandes pour savoir quelles tâches automatiser . Ainsi pour étoffer vos scripts, je vous recommande de visiter la liste des commandes du shell Linux (ou Unix).
I - Les éditeurs de texte en mode console
Comme il a été dit plus haut, il vous faut un éditeur de texte pour coder en Bash. Voici donc quelques éléments utiles qui pourront vous servir à l'utilisation des éditeurs en mode console.
1) L'éditeur vim :
- vim ou vi : lance l'éditeur
- dd : supprimer la ligne sur laquelle est positionné le curseur
- 2dd ou 3dd (etc) : supprimer 2 lignes, 3 lignes, etc à partir du curseur
- [echap] + :3,5d : supprimer les lignes 3 à 5 du fichier
- [echap] + :w : sauvegarder
- [echap] + :q! : quitter sans sauvegarder
- [echap] + :wq ou :x : quitter en sauvegardant
- [echap] + [i] ou [echap] + [a] : Ajouter du texte
- vimtutor : ouvre un minituto sur le fonctionnement de vim*
* il est possible que le vim installé sur votre distribution soit un vim restreint proche de l'ancien éditeur vi (avec le paquet vim-tiny) dans ce cas il faut installer le paquet vim pour avoir ce minituto (il est d'ailleurs préférable d'installer ce paquet tout court).
2) L'éditeur Emacs :
- emacs NomDuFichier -nw : pour lancer Emacs en console
- [ctrl] + [x] puis [ctrl] + [c] : pour quitter (on vous demandera si vous voulez sauvegarder le fichier ...)
Pour aller plus loin avec Emacs, voici quelques tutoriels intéressants :
Introduction à l'éditeur de texte Emacs sous linux (developez.com)
3) L'éditeur Nano :
- nano : lance l'éditeur
- [ctrl] + [x] : pour quitter (on vous demandera si vous voulez sauvegarder ...)
#!/bin/bash
Rappelons, que le Bash est principalement une évolution de sh. Ainsi,
il est possible, au stade des connaissances acquise avec ce tutoriel, d'écrire
en première ligne :
#!/bin/sh
Dans le cas ci-dessus, on fait appel au shell sh et non au Bash. C'est parfois préférable pour que votre script soit standard et qu'il fonctionne ainsi sur toutes les plateformes de type Unix qui parfois, ne disposent pas de Bash (ça reste assez rare tout de même).Faites ensuite chmod +x nom_du_script en console afin de donner des droits d'exécution en console à ce fichier ("NomDuScript" étant le nom de votre fichier, déplacez le fichier sur le terminal pour retrouver son chemin absolu).
Vous pouvez aussi faire chmod u+x nom_du_script si vous ne souhaitez accorder les droits d'exécution qu'à l'utilisateur propriétaire.
Pour exécuter le script, après lui avoir donné les droits d'exécution, il suffit de rentrer le chemin absolu ou tout simplement de faire ./chemin_relatif_du_script (./nom_du_script si vous êtes, via le shell, dans le répertoire ou se situe le script).
Exemple : On va prendre l'exemple des commandes echo, man, read et sleep.
Voici le script que cela devrait donner :
#!/bin/bash
# ceci est commentaire
echo "La page du man va s'ouvrir ..." #(1)
read # (2)
man man # (3)
sleep 2 # (4)
(1) Ici echo affichera la ligne "La page du man va s'ouvrir" (2) read marque une pause jusqu'à ce que l'on appuie sur une touche
(3) man man ouvre une page de manuel sur le manuel en console
(4) sleep 2 marquera deux secondes de pause
Vous faite ensuite chmod +x NomDuScript, et vous pourrez lancer ce script (cible) dans un terminal avec ./NomDuScript. Celui-ci ouvriras la page du man sur le man.
Cette commande est utile pour avoir le temps de lire les messages d'erreurs si jamais la commande précédente ne s'exécute pas correctement ... Par exemple, imaginez que ce script serve à lancer un exécutable, mais que vous ayez déplacé cet exécutable, cette commande vous permettrait d'avoir le temps de lire le message d'erreur avant que le script ne se ferme. Vous auriez aussi pu mettre read à la place, ainsi, le script ne se fermerait pas avant que vous n'appuyez sur une touche ...
III - Les variables :
Les variables en Bash, ne servent pas qu'à désigner une valeur, elle peuvent désigner du texte, une commande Bash, etc. Déclarer une variable en Bash est très simple, il suffit de l'introduire, par une affectation, comme ceci :
#!/bin/bash
NomDeLaVariable=X #(1)
Attention : Il ne faut pas avoir d'espaces de part et d'autres du signe = !
Pour demander le contenu d'une variable, il faut utiliser read comme ceci :
#!/bin/bash
read Variable # saisie de la valeur de la variable
Dans l'exécution, il faut saisir la valeur de la variable puis appuyer sur [ENTER].Pour l'afficher, il suffit d'utiliser echo comme ceci :
echo $NomDeLaVariable #(1)
(1) $ sert ici à afficher le contenue de la varible qui peut être une valeur, du texte (ne pas oublier les guillemets), une commande, etc#!/bin/bash
Variable=commande_bash # (1)
$Variable # (2)
(1) Ici le contenu de la variable (Variable) est une commande de la console
(2) Ici $ permet ici d'exécuter la commande
Exemple d'application sur les variables :
#!/bin/bash
echo "Quelle commande souhaitez vous exécuter ?"
read Commande # saisie de la commande
$Commande # exécution de la commande
read
Autres exemples :
#!/bin/bash
Texte="La man page du man va s'ouvrir ..."
echo $Texte # affichage du texte
man man
et
#!/bin/bash
echo "écrivez le texte que vous souhaitez afficher"
read Texte # saisie du texte
echo "$Texte" # affichage du texte
read
IV - Les tests (ou conditions) en Bash :
1) Le test if :
Le test if peut s'écrire de deux manière. Voici les deux syntaxes possibles :
if test $Variable #condition
then # alors
# vos commandes ici
fi # fin du bloc if (fi = if à l'envers)
if [ $Variable #condition ]
then # alors
# vos commandes ici
fi # fin du bloc if
Il est également possible d'utiliser les conditions else (sinon) et elif (de else if qui signifie sinon si) dans le même bloc :
if [ $Variable #condition ]
then # alors
# vos commandes ici
elif [ $Variable #condition ]
then
else
fi # fin du bloc if
Attention aux espaces après le [ et avant le ]. Vous remarquerez aussi qu'il n'y a pas de then après le else ...
Certains opérateurs sont toutefois particuliers en Bash, en voici une liste :
Opérateurs | Description | Exemple |
opérateurs de fichiers |
||
-e | test si le fichier existe | if [ -e /etc/group ] |
-d | test si le fichier est un répertoire | if [ -d /home ] |
-f | test si le fichier est un fichier ordinaire | if [ -f ~/fichier ] |
-L | test si le fichier est un lien symbolique | if [ -L /bin/sh ] |
-r | test si le fichier est lisible (r) | if [ -r /etc/passwd ] |
-w | test si le fichier est modifiable (w) | if [ -w /var/log ] |
-x | test si le fichier est exécutable (x) | if [ -x /sbin/ifconfig ] |
-nt | test si un fichier est plus récent qu'un autre | if [ ~/f1 -nt ~/f2 ] |
-ot | test si un fichier est plus ancien qu'un autre | if [ ~/f1 -ot ~/f2 ] |
comparaison entre chaînes | ||
-z | test si la chaine est vide | if [ -z "$str" ] |
-n | test si la chaine est non vide | if [ -n "$str" ] |
= | test si les deux chaînes sont égales | if [ "$str" = "chaine" ] |
!= | test si les deux chaînes sont différentes | if [ "$str" != "chaine" ] |
comparaisons sur des nombres | ||
-eq | égalité | if [ $nb -eq 10 ] |
-ne | inégalité | if [ $nb -ne 10 ] |
-lt | infériorité stricte ( < ) | if [ $nb -lt 10 ] |
-le | infériorité non stricte ( <=) | if [ $nb -le 27 ] |
-gt | supériorité stricte ( > ) | if [ $nb -gt 10 ] |
-ge | supériorité non stricte ( >=) | if [ $nb -ge 10 ] |
Exemple :
On va prendre un exemple : Un script qui vous demande si vous voulez afficher la man page du man avec 0 et 1 (1= oui, 0= non).
#!/bin/bash
echo "Voulez-vous afficher la man page du man ?"
read Variable # saisie de la variable
if test $Variable -eq 1 # si Variable vaut 1
then # alors
man man
fi # fin du bloc if
read
echo "Voulez-vous afficher la man page du man ?"
read Variable # saisie de la variable
if [ $Variable -eq 0 ] # si Variable vaut 1
then # alors
fi # fin du bloc if
read
2) Le test case :
Le test case est analogue au switch en C, il permet d'éviter une longue et fastidieuse succession de blocs if dans certains cas. Voici la syntaxe d'un test case.
read Variable # saisie de la valeur de la variable
case $Variable in
Valeur1) # (1)
#Commande 1 ;;
Valeur2) # (2)
#Commande 2 ;;
# ...
*) # (3)
# Commande qui s'éxécute par défaut ;;
esac # fin du bloc case
(1) si l'utilisateur choisi la valeur 1, alorsla commande 1 s'exécute
(2) si l'utilisateur choisi la valeur 2, alorsla commande 2 s'exécute
(3) si l'utilisateur choisi autre chose, la commande par défaut s'exécute
N'oubliez pas le esac (case à l'envers) pour marquer la fin du bloc case.
Exemple :
#!/bin/bash
echo "=== Menu === "
echo "1. Royal Cheese "
echo "2. Mc Deluxe "
echo "3. Filet-o-Fish "
echo "4. Big Mac "
echo "Votre choix ?"
read choixMenu # saisie de la valeur de la variable
case $choixMenu in
1)
echo "Vous avez choisi le Royal Cheese. Bon choix ! " ;;
2)
echo "Vous avez choisi le Mc Deluxe. Berk, trop de sauce..." ;;
3)
echo "Hum pas mal mais c'est bien petit :( " ;;
4)
echo "Vous avez choisi le Big Mac. Vous devez avoir tres faim !";;
*)
echo "Vous n'avez pas rentre un nombre correct. Vous ne mangerez rien du tout !" ;;
esac # fin du bloc case
echo "Appuyez sur une touche pour continuer ..."
read
V - Les boucles :
Les boucles permettent de répéter une ou plusieurs
opérations tant qu'une condition reste validée.
1) Le boucle while :
Voici comment se construit une boucle while :
while [ #condition ]
do
# instructions à répéter
done
Et voici la deuxième syntaxe possible :
while test #conditiondo
# instructions à répéter
done
Exemple :
On veut créer une boucle qui répète "vive le Bash !" tant que la valeur d'une variable ne vaut pas 0.
quitter=1
while [ $quitter -ne 0 ]
do
echo "Appuyez sur 0 pour quitter ..."
read quitter
echo "vive le Bash !"
done
echo "bye !"
read
voici la deuxième manière d'écrire ce script :
#!/bin/bash
quitter=1
while test $quitter -ne 0
do
echo "Appuyez sur 0 pour quitter ..."
read quitter
echo "vive le Bash !"
done
echo "bye !"
read
Autre exemple :
exemple inverse du précédant (on répète la phrase "vive le bash !"
tant qu'une variable vaut 0) :
continuer=0
while test $continuer -eq 0
# ou -> while [$continuer -eq 0 ]
do
echo "Appuyez sur 0 pour répéter ..."
read quitter
done
echo "bye !"
read
2) La boucke until
La boucle until s'utilise de la même façon que la boucle while et possède les mêmes syntaxes. Cependant elle prend en paramètre l'expression de condition inverse que celle que prendrait while.
Exemple :
#!/bin/bash
quitter=1
until [ $quitter -eq 0 ]
do
echo "Appuyez sur 0 pour quitter ..."
read quitter
echo "vive le Bash !"
done
echo "bye !"
read
Ce code parvient au même résultat que celui du premier exemple donné pour la boucle while.
3) La boucle for :
J'en vient directement à l'intérêt de la boucle for par rapport à la boucle while
à l'aide d'un exemple : on veut par exemple répeter la phrase "vive Linux"
tant que la valeur d'une variable est comprise entre 0 et 10 (exclus).
#!/bin/sh
i=0
for i in `seq 0 10`
do
echo "vive Linux !"
read i
done
echo "bye !"
read
Ceci aurait pu s'écrire de la manière classique :
#!/bin/sh
i=0
for (( i=0 ; i<$value ; i++ ))
do
echo "vive Linux !"
done
echo "bye !"
read
VI - Les fonctions :
Les fonctions sont très simples à faire en Bash, elles permettent
de ne pas répéter plusieurs fois le même bloc. Il faut indiquer
clairement lorque vous déclarez une fonction.
Exemple :
#!/bin/sh
function hello # déclaration de la fonction
{
echo "Salut $1 !"
#le $1 sert à insérer le contenu d'une variable,
celui de la variable qui suivra l'appel de la fonction
}
echo "Comment t'appelles tu ?"
read name
hello $name
read
L'exemple utile de la fonction pause :