Les scripts bash
Notre premier script
Bash n'est pas qu'un simple interpréteur de commandes. Il permet d'effectuer une suite de commandes rassemblées dans un fichier exécutable, appelé "script". A ce titre, bash est un véritable langage de programmation.
Comme tout bon programmeur, nous allons commencer par un "helloworld". Il s'agira simplement d'afficher le texte "hello world !" à l'écran.
Pour préciser à linux que l'interpréteur de commandes utilisé est bash (utile si ce n'est pas le shell par défaut), tout script va commencer par la ligne #!/bin/bash.
Pour insérer un commentaire, mettez un # au début de la ligne. Chaque instruction se trouvera sur un ligne.
Et voilà, c'est tout ce que nous avons besoin de connaitre pour écrire un simple script. Maintenant, ouvrer votre éditeur de texte préféré et tapez les lignes ci-dessous. Puis sauvegardez le tout sous le nom helloworld.sh.
#!/bin/bash # premier script bash echo "hello world !"
Comme notre script vient d'être créé, il faut préciser au système que c'est un fichier exécutable en tapant chmod +x helloworld.sh. C'est fait une fois pour toutes, et il n'est heureusement pas nécessaire de recommencer à chaque modification du script.
Maintenant exécutons notre script en faisant précéder le nom de "./". Le "./" sert à indiquer que le script se trouve dans le répertoire courant. C'est indispensable si le répertoire courant n'est pas inclu dans la variable PATH (plus dinfos sur PATH ici).
chmod +x helloworld.sh $ ./helloworld.sh hello world ! $
Et voilà, c'est pas plus compliqué que ça ! Bien sûr, ce premier script n'est pas d'une utilité foudroyante. Mais si vous devez taper régulièrement une même suite d'instructions, alors il peut être pratique de les rassembler dans un script. Par exemple, pour configurer votre firewall, plutôt que de taper toutes les commandes iptables bien complexes à chaque connexion, vous n'avez qu'à faire un script que vous lancez automatiquement à chaque démarrage.
Les variables
Les variables peuvent contenir n'importe quelle valeur. On ne déclare pas le type de la variable, contraitement à beaucoup de langages. Ici, il est déterminé automatiquement : nombre entier ou chaines de caractère.
On les déclare en mettant leur nom suivi du signe '=' et de la valeur, sans espaces. Si la valeur est une suite de caractès sééparés par des espaces, il faudra alors mettre des guillemets ou des apostrophes. Pour utiliser les variables, on met leur nom précédé du signe '$' sans espace.
exemple :
#!/bin/bash nb=25 mon_texte="bonjour tout le monde" echo $nb echo $mon_texte
A l'écran ça nous donne :
$ ./test.sh 25 bonjour tout le monde $
Voici maintenant un exemple de manipulation des variables, où on voit qu'on ne peut pas faire n'importe quoi avec les variables.
#!/bin/bash nb=25 mon_texte="bonjour tout le monde" mon_texte_2="coucou" echo $nb echo $mon_texte echo $mon_texte_2 let $[ nb=$nb+1 ] let $[ mon_texte=$mon_texte+1 ] # erreur faite exprès !! mon_texte_2=$mon_texte_2" les gens" echo "nb + 1 = $nb" echo "mon_texte + 1 = $mon_texte" echo $mon_texte_2
Et le résultat :
$ ./test.sh 25 bonjour tout le monde coucou ./test.sh: mon_texte=bonjour tout le monde+1 : syntax error in expression (error token is "tout le monde+1 ") nb + 1 = 26 mon_texte + 1 = 0 coucou les gens
On contate bien qu'on ne peut pas faire d'opération arithmétique avec des chaines de caractères, ce qui est normal, évidement. Dans un langage compilé avec déclaration du type de variable, comme le C, ont aurait été averti dès la compilation. Ici, il faut bien faire attention à ce qu'on fait. C'est la contrepartie de la souplesse apportée par bash.
Quelques variables utiles
- $$ : affiche le numéro de processus (pid) du shell
- $! : affiche le pid de la dernière commande lancée en tâche de fond (avec &)
- $? : affiche la valeur retrounée par la dernière commande
- $ : affiche la liste des options avec lesquelles le shell a été appelé
Les commandes composées (; | & || && $() {} ``)
Les commandes qu'on a tapé jusque-là sont des commandes simples : une seule commande par ligne, les unes à la suite des autres. Bash permet de faire des commandes composées, c'est à dire plusieurs commandes sur la même lignes, qui vont influer les unes sur les autres.
les commandes séquentielles
Elles s'exécutent l'une après l'autre, exactement comme si on les avait mises sur deux lignes différentes. Le seul intérêt est d'avoir un code plus clair dans certains cas. On sépare simplement les commandes par un point-virgule.
commande1 ; commande2
les commandes redirigées
Le résultat de la commande1 est renvoyé à la commande2.
syntaxe :
commande1 | commande2
exemple :
ps -aux | grep x
Dans l'exemple, on va afficher tous les processus qui contiennent le caractère 'x'.
les commandes en parallèle
On exécute les deux commande1 et commande2 en parallèle. Commande1 est exécutée en tâche de fond.
commande1 & commande2
les commandes "OU exclusif"
Commande2 est exécutée SI et seulement SI commande1 a échoué.
commande1 || commande2
les commandes "ET exclusif"
Commande2 est exécutée SI et seulement SI commande1 a réussi.
commande1 && commande2
les commandes passées en paramètre
Commande2 sert de paramètre à commande1
syntaxe :
commande1 $(commande2) OU commande1 `commande2`
Le caractère ` s'obtient en faisant 'Alt-Gr + 7'. C'est l'apostrophe à l'envers.
exemple : on affiche l'heure
#!/bin/bash heure=$(date +%T) echo $heure
Les trois syntaxes suivantes donnent le même résultat :
#!/bin/bash heure=`date +%T` echo $heure
#!/bin/bash echo $(date +%T)
#!/bin/bash echo `date +%T`
les séries de commandes
On regroupe des commandes entre parenthèses ou accolades. Contrairement aux accolades, les instructions entre parenthèses se déroulent dans un shell secondaire, indépendant du shell actuel. L'utilisation des accolades est donc plutôt conseillée. Avec les accolades, la dernière commande doit se terminer avec un point-virgule.
{ commande1 ; commande2; } OU ( commande1; commande2 )
exemple : on affiche la date et la liste des fichiers, et on envoi le tout vers l'imprimante, plutôt que vers l'écran.
{ date; ls -l; } | lpr
Ecriture à l'écran / lecture au clavier (echo / read)
Ecriture à l'écran
L'écriture à l'écran est très simple, et on l'a déjà vue dans notre premier script. On utilise la commande 'echo' suivie du texte à afficher.
Le texte à afficher peut être entouré de guillemets (") ou de côtes ('), mais ça n'est pas obligatoire. ATTENTION : si on utilise les côtes, les variables (appelées avec $, voir partie 2 - les variables) ne seront pas remplacées par leur valeur ; $variable sera considéré comme un texte (voir exemple ci-dessous).
#!/bin/bash nom=fred echo 1. Mon nom est $nom. echo "2. Mon nom est $nom." echo '3. Mon nom est $nom.' echo -n "On ne retourne pas a la ligne."
Et voilà ce que ça nous donne :
$ ./test.sh 1. Mon nom est fred. 2. Mon nom est fred. 3. Mon nom est $nom. <== la variable $nom n'est pas remplacée par sa valeur ! On ne retourne pas a la ligne.$
Dans l'exemple, on voit aussi une option pratique de echo, qui est l'option -n. Ca permet de ne pas revenir à la ligne à la fin. Dans l'exemple ça ne sert à rien, mais ça va nous servir tout de suite. Si vous voulez connaitre toutes les options de echo, tapez "man echo" dans votre console.
Lecture au clavier
La lecture au clavier se fait avec la commande 'read'. La syntaxe est "read valeur" ou "read val1 val2 val3". Si on rentre une seule valeur, elle sera stockée dans la première variable. Si on rentre plusieurs valeurs, séparées par des espaces, alors la première valeur ira dans la première variable, la deuxième valeur dans la deuxième variable, et ainsi de suite. S'il y a plus de valeurs que de variables, la dernière variable contient toutes les dernières valeur. S'il y a plus de variables que de valeurs, les dernières variables seront vides. Si on ne précise aucun nom de variable, la variable par défaut est "REPLY".
Tout ça sera peut-être plus clair avec l'exemple qui suit. Voici le programme :
#!/bin/bash echo -n "entrez ce que vous voulez : " read val1 val2 val3 echo val1=$val1 echo val2=$val2 echo val3=$val3
Et voilà les différants résultats obtenus, en fonction du nombre de valeurs qu'on lui donne :
$ ./test.sh entrez ce que vous voulez : a b c val1=a val2=b val3=c $ ./test.sh entrez ce qe vous voulez : a b c d e val1=a val2=b val3=c d e $ ./test.sh entrez ce que vous voulez : a b val1=a val2=b val3=
Le passage de paramètres
Lorsqu'on lance un script, plutôt que de demander les paramètres après avec la commande read, on peut aussi les rentrer dès le lancement du script. On appelle ça le passage de paramètres. La syntaxe est la suivante :
./script param1 param2 param3
On a alors plein de variables qui nous permettent de récupérer chaque paramètre, ainsi que leur nombre.
- $# : nombre de paramètres
- $* : affiche l'ensemble des paramètres
- $@ : affiche l'ensemble des paramètres comme $*. La différence est que $* correspond à une seule valeur, alors que $@ correspond à autant de valeurs qu'il y a de paramètres
- $0 : affiche le nom du script
- $1, $2, ..., $9, ${10}, ... : correspondent aux paramètres n°1, 2, etc. Pour les paramètres à plusieurs chiffres, il faut mettre les chiffres entre crochets.
Aller, on va se faire un petit exemple pour voir si vous avez bien compris :
#!/bin/bash echo "nom du script=$0" echo "nombre de parametres : $#" echo '$*'=$* echo '$@'=$@ echo "param1=$1" echo "param2=$2" echo "param3=$3" echo "param4=$4"
Ce qui nous donne à l'écran :
$ ./test.sh a b c 123 nom du script=./test.sh nombre de parametres : 4 $*=a b c 123 $@=a b c 123 param1=a param2=b param3=c param4=123
la commande shift
La commande 'shift n' supprime les 'n' premiers paramètres de la liste, et décale la valeur des paramètres. Ainsi, la commande 'shift 3' supprime les trois premiers paramètres. Donc param4 devient param1, param5 devient param2, etc. De plus, la variable $# est diminuée de 'n'.
Rien ne vaut un exemple pour y voir plus clair :
#!/bin/bash echo "nombre de parametres : $#" echo "param1=$1" echo "param2=$2" echo "param3=$3" echo "param4=$4" echo "param5=$5" shift 3 echo "apres 'shift 3' il nous reste $# parametres" echo "param1=$1" echo "param2=$2" echo "param3=$3" echo "param4=$4" echo "param5=$5"
Ce qui nous donne, à l'exécution :
$ ./test.sh a b c d e nombre de parametres : 5 param1=a param2=b param3=c param4=d param5=e apres 'shift 3' il nous reste 2 parametres param1=d param2=e param3= param4= param5=
Les structures conditionnelles (if then else while until)
généralités
Une structure conditionnelle est une structure dans laquelle on effectue un test. Le script se comportera de façon différente en fonction du résultat du test. On peut aussi réaliser des boucles tant que le test est vrai.
Les tests peuvent porter sur des fichiers (et/ou répertoires), sur des entiers et sur des chaines de caractères. Leur syntaxe n'est pas la même dans tous les cas. On peut aussi faire des combinaisons de tests.
Il existe deux façons de faire les tests : soit entre crochets, soit avec la commande 'test'.
SI [ tests ] ALORS ... SI test tests ALORS ...
Attention à ne pas oublier l'espace après le premier crochet, et avant le dernier !
Tests sur les fichiers/répertoires
Voici une liste des tests possibles sur les fichiers et/ou répertoires :
- "-e fichier" : vrai si le fichier/répertoire existe.
- "-s fichier" : vrai si le fichier à une taille supérieure à 0.
- "-r fichier" : vrai si le fichier/répertoire est accessible en lecture.
- "-w fichier" : vrai si le fichier/répertoire est accessible en écriture.
- "-x fichier" : vrai si le fichier est exécutable ou si le répertoire est accessible.
- "-O fichier" : vrai si le fichier/répertoire appartient à l'utilisateur.
- "-G fichier" : vrai si le fichier/répertoire appartient au groupe de l'utilisateur.
- "-b nom" : vrai si nom représente un périphérique (pseudo-fichier) de type bloc (disques et partitions de disques généralement).
- "-c nom" : vrai si nom représente un périphérique (pseudo-fichier) de type caractère (terminaux, modems et port parallèles par exemple).
- "-d nom" : vrai si nom représente un répertoire.
- "-f nom" : vrai si nom représente un fichier.
- "-L nom" : vrai si nom représente un lien symbolique.
- "-p nom" : vrai si nom représente un tube nommé.
- "fichier1 -nt fichier2" : vrai si les deux fichiers existent et si fichier1 est plus récent que fichier2.
- "fichier1 -ot fichier2" : vrai si les deux fichiers existent et si fichier1 est plus ancien que fichier2.
- "fichier1 -ef fichier2" : vrai si les deux fichiers représentent un seul et même fichier.
Tests sur les entiers
- "entier1 -eq entier2" : vrai si entier1 est égal à entier2.
- "entier1 -ge entier2" : vrai si entier1 est supérieur ou égal à entier2.
- "entier1 -gt entier2" : vrai si entier1 est strictement supérieur à entier2.
- "entier1 -le entier2" : vrai si entier1 est inférieur ou égal à entier2.
- "entier1 -lt entier2" : vrai si entier1 est strictement inférieur à entier2.
- "entier1 -ne entier2" : vrai si entier1 est différent de entier2.
Tests sur les chaines de caractères
Les chaines doivent être entourées par des guillemets.
- "-n "chaîne"" : vrai si la chaîne n'est pas vide.
- "-z "chaîne"" : vrai si la chaîne est vide.
- ""chaine1" = "chaine2"" : vrai si les deux chaînes sont identiques.
- ""chaine1" != "chaine2"" : vrai si les deux chaînes sont différentes.
Les combinaisons de tests
Les combinaisons de tests sont utilisées quand on doit faire plusieurs tests simultanément, c'est à dire, quand on doit répondre à plusieurs conditions.
On utilise les opérateurs && et || comme dans les commandes composées. L'opérateur ! sert à inverser la condition.
- SI test ALORS commandes FIN : exécute les commandes si test est VRAI
- SI ! test ALORS commandes FIN : exécute les commandes si test est FAUX
- SI test1 && test2 ALORS commandes FIN : exécute les commandes si test1 ET test2 sont vrais tous les deux
- SI test1 -a test2 ALORS commandes FIN : pareil de précédemment, avec une autre notation
- SI test1 && ! test2 ALORS commandes FIN : exécute les commandes si test1 est VRAI ET test2 est FAUX
- SI test1 || test2 ALORS commandes FIN : exécute les commandes si test1 OU test2 sont VRAIS
- SI test1 -o test2 ALORS commandes FIN : pareil de précédemment, avec une autre notation
- SI ! { test1 || test2 } ALORS commandes FIN : exécute les commandes si NI test1 NI test2 sont VRAIS
Un exemple avec OU :
if [ "$var" == "toto" ] || [ "$var" == "titi" ] then echo "ok" fi
structure SI ... ALORS
La syntaxe de cette structure est :
if test; then action-1 action-2 ... action-n; fi
Il faut bien mettre un point-virgule après le test et aprè la dernière action. On termine la structure avec la commande fi.
structure SI ... ALORS ... SINON
La syntaxe est :
if test; then action1; else action2; fi
Si le test est vrai, on exécute l'action1 (ou le groupe d'actions1), sinon, on exécute l'action2 (ou le groupe d'actions2). Bien mettre le point virgule après le test et chaque commande ou groupe de commandes.
structure SI ... ALORS ... SINON SI ... ALORS ... SINON
syntaxe :
if test1; then action1; elif test2; then action2; else action3; fi
Si test1 est vrai, on exécute l'action1, sinon, si test2 est vrai, on exécute l'action2, sinon, on exécute l'action3. Bien mettre le point virgule après chaque test et chaque commande ou groupe de commandes.
On peut avoir autant de 'elif' qu'on veut. Voyons un exemple d'utilisation de cette structure :
#!/bin/bash echo -n "Entrez un nombre entier : " ; read nombre if [ $nombre -lt 0 ]; then echo "$nombre est negatif"; elif [ $nombre -gt 0 ]; then echo "$nombre est positif"; else echo "$nombre est egal a zero"; fi
Et voilà le résultat :
$ ./test.sh Entrez un nombre entier : 12 12 est positif $ ./test.sh Entrez un nombre entier : -5 -5 est negatif $ ./test.sh Entrez un nombre entier : 0 0 est egal a zero
structure TANT QUE ... FAIRE
Il existe deux commandes pour faire ça : while et until. While va répéter la boucle tant que le test est vrai. Until va répéter la boucle jusqu'à ce que le test soit vrai.
La syntaxe des deux commandes est :
while test; do action1 action2; done until test; do action1 action2; done
Comme avec les structures précédentes, on met un point-virgule après le test et après le groupe d'actions.
Il arrive très souvant, en programmation, qu'on veuille répéter une opération un certain nombre de fois. Dans ce cas, on utilise un entier qui va nous servir de compteur. Pour incrémenter ce compteur, on utilise la commande let suivie de l'opération à effectuer, selon la syntaxe suivante :
let $[ commande ]
Voici un exemple très simple, qui affiche les nombres de 1 à 10.
#!/bin/bash i=1 # on initialise le compteur while [ $i -le 10 ]; do echo $i let $[ i+=1 ] # incremente i de 1 a chaque boucle done
Et on obtient :
./test.sh 1 2 3 4 5 6 7 8 9 10
L'instruction "i+=1" sert à incrémenter i de 1. C'est une syntaxe employée dans de nombreux langage, mais qui n'est peut-être pas claire pour le débutant. On peut la remplacer par "i=$i+1", ce qui nous donne "let $[ i=$i+1 ]". Celle-ci est plus facilement compréhensible.
Les autres structures (for in do case select)
structure POUR chaque élément de la liste FAIRE ...
Cette structure nous permet de faire une action pour chaque élément d'une liste. La liste peut être donnée directement, ou être le résultat d'une commande.
Syntaxe :
for element in liste_des_elements; do actions; done
On met un point-virgule après la liste des éléments et après le groupe d'actions.
Exemple 1, où on tape la liste manuellement :
#!/bin/bash for mois in janvier fevrier mars avril; do echo $mois; done
Le résultat est :
./test.sh janvier fevrier mars avril
Exemple 2, où la liste est le résultat d'une commande. Au lieu de faire un exemple bête comme j'en ai l'habitude... Si, si... On va faire un script très pratique, qui permet de renomer des fichiers par lot. On appelle le script avec deux paramètres : le premier est l'extention actuelle des fichiers, le second est l'extention qu'on veut donner. Et comme maintenant vous êtes très forts, on va même vérifier que le nombre de paramètres est bon. C'est plus prudent avec les étourdis !
#!/bin/bash if ! [ $# -eq 2 ]; then echo "Le nombre de parametres doit etre de 2 (ancienne-extension nouvelle-extention) !" else ext1=$1 ext2=$2 for file in `ls *.$ext1`; do mv $file ${file%.$ext1}.$ext2; done fi
Voilà le résultat :
$ ls a.txt b.txt c.txt renome.sh $ ./renome.sh Le nombre de parametres doit etre de 2 (ancienne-extension nouvelle-extention) ! $ ./renome.sh txt tmp $ ls a.tmp b.tmp c.tmp renome.sh
Et voilà le travail ! Tous nos fichiers .txt ont été renomés en .tmp. Et nous avons été avertis quand le nombre de paramètres n'était pas bon.
structure DANS chacun des cas suivants FAIRE ...
Pour ce type de structure, on utilise la commande case. Cette commande est équivalente à une série de if ... elif ... elif ... elif ... else ... fi, mais ç apparait de façon beaucoup plus claire et lisible.
Syntaxe :
case valeur in cas_1) action_1;; cas_2) action_2;; cas_3) action_3;; *) action_sinon;; esac
Pour chaque possibilité, on a une action associée. Si aucun des cas n'est rencontré, c'est l'action par défaut (correspondant à "*)") qui est exécutée.
Chaque action ou suite d'actions se termine par un double point-virgule. La structure se termine par "esac" ("case" écrit à l'envers).
La commande select
Syntaxe :
select valeur in liste_de_valeurs; do actions; done
La commande select affiche un menu qui vous propose le choix parmis la liste définie. Chaque ligne est numérotée en partant de 1. Select affiche une phrase qui vous demande d'entrer votre choix. Cette phrase est contenu dans la variable PS3 qu'il faudra initialiser avant (par défaut, elle contient "#?"). Une fois que vous avez validé votre réponse, elle est mémorisée dans la variable REPLY.
Select repose indéfiniment la même question, jusqu'à ce qu'on quitte le script avec les touches ctrl-c. Pour éviter ça, on utilise la commande "break" qui permet de sortir de la structure pour passer à la suite du script. Il est fortement conseillé d'utiliser select en combinaison avec case. Ainsi, on peut facilement orienter le déroulement du script en fonction de la valeur choisie.
Comme tout ça n'est pas vraiment simple dit comme ça, on va faire un exemple pour montrer que finalement ça n'est pas si complexe que ça en a l'air. Au contraire, on peut faire très facilement un menu.
#!/bin/bash PS3="> selectionnez un plat : " # definie l'invite du menu echo " -- menu du jour -- " # affiche un titre select choix in cassoulet pizza "salade du chef" "quitter (q|Q)"; do case $REPLY in 1) echo "Voici votre $choix." echo "Desirez-vous autre chose ?";; 2) echo "Une pizza ? Excellent choix !" echo "Desirez-vous autre chose ?";; 3) echo "Et une $choix, une !" echo "Desirez-vous autre chose ?";; 4|Q*|q*) echo "Au revoir" # on quitte en appuyant sur 4, ou en tapant un mot commancant par Q ou q break;; *) echo "Je n'ai pas compris votre commande. Veuillez repeter svp.";; esac done
Voilà ce que ça donne à l'écran :
$ ./test.sh -- menu du jour -- 1) cassoulet 2) pizza 3) salade du chef 4) quitter (q|Q) > selectionnez un plat : azerty Je n'ai pas compris votre commande. Veuillez repeter svp. 1) cassoulet 2) pizza 3) salade du chef 4) quitter (q|Q) > selectionnez un plat : 2 Une pizza ? Excellent choix ! Desirez-vous autre chose ? 1) cassoulet 2) pizza 3) salade du chef 4) quitter (q|Q) > selectionnez un plat : q Au revoir
Et voilà comment qu'on est trop forts !
Les fonctions
Pour simplifier et rendre plus lisible les scripts, bash permet l'utilisation de fonctions. Une fonction est un sous-programme qui peut être appelé n'importe quand, et aussi souvant que nécéssaire. On peut lui envoyer des variables, et elle peut nous retourner un résultat. A l'intérieur d'une fonction, on peut créer une variable locale (qui n'existe qu'à l'intérieur de la fonction) avec le mot clé "local".
On accède aux paramètres de la fonction de la même façon que dans un script, avec les variables $#, $*, $@, $1, $2, etc. Seul $0 ne change pas (pour rappel, $0 affiche le nom du script).
Pour renvoyer un valeur au programme principal, c'est le mot clé "return" qui est utilisé. Sinon, c'est le résultat de la dernière commande exécutée qui est renvoyé.
Une fonction peut s'appeler elle-même. On dit qu'elle est récursive.
Attention : il faut utiliser la commande "exit" avec prudence, car elle ne termine pas seulement la fonction, mais aussi le script !
Pour déclarer une fonction, soit on met un nom suivit de "()", soit on met le mot clé "function" suivit d'un nom (sans parenthèses). Puis on met le contenu de la fonction entre crochets.
Remarque 1 : on ne doit pas mettre à la fois le mot clé "function" et les parenthèses, bien que certains shells récents l'acceptent.
Remarque 2 : il n'y a pas d'importance à utiliser l'une ou l'autre syntaxe, mais la syntaxe avec les parenthèses est plus portable avec les très vieux shells.
Voici la syntaxe :
# declaration de la fonction nom_de_la_fonction() # ou : function nom_de_la_fonction { actions } # programme principal ... actions ... nom_de_la_fonction # sans parentheses nom_de_la_fonction $variable # si on doit passer un parametre a la fonction variable=$? # recupere le resultat de la fonction ... actions ...
Et comme rien ne vaut un exemple, le voici. Dans cet exemple, on déclare deux fonctions ; l'une calcule le carré d'un nombre, l'autre sa factorielle.
#!/bin/bash # utilisation des fonctions function carre { return $[ $1 * $1 ]; } function factorielle { local x=$1 local resultat=1 while [ $x -ge 1 ]; do resultat=$[ $x * $resultat ] let $[ x-= 1 ]; done return $resultat; } # programme principal echo -n "Tapez un nombre positif : " read nb carre $nb ; CARRE=$? # execute la fonction et recupere la valeur echo "nb * nb = $CARRE" factorielle $nb ; FACTORIELLE=$? # execute la fonction et recupere la valeur echo "factorielle : $nb! = $FACTORIELLE"
Ce qui nous donne à l'écran :
$ ./test.sh Tapez un nombre positif : 5 nb * nb = 25 factorielle : 5! = 120
On remarque bien que le programme principal est beaucoup plus lisible que si on n'avait pas fait appel aux fonctions. Et bien sûr, si on doit faire appel plusieurs fois à la même fonction, l'interêt est encore plus évident.
Pour aller plus loin
Nous avons fait le tour de toutes les principales fonctionnalités des scripts bash. Pour aller plus loin, je vous laisse chercher sur le net, ou dans des livres. Je vous donne quand même les deux liens suivants qui m'ont beaucoup aidé lors de mon apprentissage des scripts (principalement labo-linux). Ils ne vous apprendront peut-être pas beaucoup plus de choses que ce cours, mais les choses sont présentées différemment, et seront peut-être plus claires pour vous.
Bonne programmation !