
|
|
#! /bin/sh
# # Shell-script de mise en application de la récupération du résultat # d une commande. Affiche l'heure en français. heures=$(date +%H) minutes=`date +%M` echo "Il est $heures heures $minutes minutes et $(date +%S) secondes" $ ./heure Il est 12 heures 29 minutes et 42 secondes |
{ commande1 ; commande2; }, ( commande1; commande2 )
Les parenthèses et accolades permettent d'encadrer une série de commandes séparées les unes des autres par "&", "&&", "|", "||" ou " ;".
L'usage des parenthèses ou des accolades permet à l'ensemble des commandes qu'elles contiennent de subir une redirection. En effet, avec la commande "ls src ; ls bin | lpr", seul le contenu du répertoire bin est imprimé car une redirection ne s'applique qu'à la commande qui précède. Par contre, la commande " {ls src ; ls bin ; } | lpr" provoque bien l'impression du contenu des répertoires src et bin.
On préférera généralement les accolades aux parenthèses car les instructions situées entre parenthèses s'exécutent dans un shell secondaire indépendant du shell actuel (voir l'utilisation du tube, plus haut).
Attention, la dernière commande de la liste entre accolades doit être terminée par un point-virgule.
La commande "echo texte" permet d'écrire un texte à l'écran. Bien que ce ne soit pas nécessaire, pour éviter tout problème il est vivement conseillé d'encadrer le texte à afficher par des guillemets.
Si le texte à afficher est une chaîne vide, la commande provoque un saut de ligne.
L'option -n évite le saut de ligne automatique à la fin du texte.
L'option -e permet l'interprétation des caractères spéciaux utilisés avec printf(), tels l'alarme, le retour à la ligne, la tabulation, etc...
Exemples :
|
echo "Texte à afficher" echo "" echo -n "Ce texte ne sera pas suivi d'un saut de ligne" echo -e "\t\aCe texte commence par une tabulation et émet un signal sonore." |
La commande read utilisée seule permet de lire une phrase complète. La phrase lue est stockée dans la variable REPLY.
La commande "read mot1 mot2 reste" permet aussi de lire une phrase au clavier mais son premier mot est affecté à la variable mot1, son deuxième mot est affecté à mot2 et le reste de la phrase est affecté à la variable reste.
|
Exemple :
luser@localhost$ echo -n "Entrez votre nom de login et votre nom civil: "; read log nom Entrez votre nom de login et votre nom civil: moliere Jean-Baptiste Poquelin luser@localhost$ echo "$log est le nom de login de $nom" moliere est le nom de login de Jean-Baptiste Poquelin |
La commande select permet d'offrir un menu à l'utilisateur. Sa syntaxe est :
select variable in "choix1" "choix2" ... "choixN"
do
liste d'instructions
done
Le menu présenté comporte l'ensemble des choix proposés précédés d'un numéro.
Une invite est affichée et le shell attend une entrée au clavier. La variable PS3 doit contenir la chaîne d'invite ("# ? " par défaut).
Lorsque l'utilisateur a entré son choix, le corps de la boucle est exécuté. La variable REPLY contient alors ce que l'utilisateur a rentré (un numéro normalement). Si le choix de l'utilisateur correspond à l'une des propositions qui lui sont faites, la variable "variable" contient aussi la chaîne correspondante ("choix1", "choix2", ... ou "choixN").
Exemple :
|
#! /bin/sh # # menu # # Shell-script de mise en application de l'instruction select. PS3="Entrez le numéro de votre commande -> " echo "Que désirez-vous boire ?" select boisson in "Rien, merci" "Café" "Thé au lait" "Chocolat"; do if [ -z "$boisson" ]; then echo "Erreur: entrez un des chiffres proposés." 1>&2 elif [ "$REPLY" -eq 1 ]; then echo "Au revoir!" break else echo "Vous avez fait le choix numéro $REPLY..." echo "Votre $boisson est servi." fi echo done Test: luser@localhost$ ./menu Que désirez-vous boire ? 1) Rien, merci 2) Café 3) Thé au lait 4) Chocolat Entrez le numéro de votre commande -> 3 Vous avez fait le choix numéro 3... Votre Thé au lait est servi. 1) Rien, merci 2) Café 3) Thé au lait 4) Chocolat Entrez le numéro de votre commande -> 1 Au revoir! luser@localhost$ |
Avant tout, il faut savoir que toute redirection ne s'applique qu'à la dernière commande.
Dans le cas d'un série de commandes séparées par "&", "&&", "|", "||" ou " ;", si l'on veut que la redirection s'applique à l'ensemble des commandes, il faut employer des parenthèses (voir la partie "commandes composées").
L'entrée standard (stdin) peut être redirigée afin de lire dans un fichier plutôt qu'au clavier. Pour cela, placez "< fichier" en fin de commande. Exemple : pour lire la première ligne d'un fichier
luser@localhost$ read < mon_script; echo $REPLY
#! /bin/sh
luser@localhost$
La sortie standard (stdout) peut être redirigée afin d'écrire dans un fichier plutôt qu'à l'écran. Pour cela, placez "> fichier" ou ">> fichier" en fin de commande. Si l'opérateur ">>" est utilisé, le contenu actuel du fichier est conservé et le texte est ajouté en fin de fichier.
Exemple :
Pour ajouter une ligne à la fin d'un fichier :
toto> echo "FIN DU FICHIER" >> fichier
toto>
La sortie standard d'erreur (stderr) peut être redirigée afin d'écrire dans un fichier plutôt qu'à l'écran. Pour cela, placez "2> fichier" en fin de commande.
Exemple :
Pour supprimer les messages d'erreur de l'affichage :
./ma_commande 2> /dev/null
La sortie standard et la sortie standard d'erreur peuvent être redirigées ensemble afin d'écrire dans un fichier plutôt qu'à l'écran. Pour cela, placez "&> fichier" en fin de commande.
Exemple :
Pour qu'une commande n'affiche rien, même pas les erreurs
ma_commande &> /dev/null
&2" à la fin de la commande.
Exemple :
Pour afficher un message sur stderr plutôt que sur stdout :
echo "Erreur fatale, le disque est plein!" 1>&2
en ajoutant "2>&1" à la fin de la commande.
Exemple :
Pour afficher le résultat d'une commande page par page, y compris les erreurs :
ma_commande 2>&1 | more
L'entrée standard peut être lue depuis le shell-script en ajoutant "<
Pour afficher plusieurs lignes de texte sans utiliser echo à chaque fois :
cat << FIN_DU_TEXTE
Vous êtes l'utilisateur $USER.
Vous êtes situé dans le répertoire $(pwd).
Merci de votre visite.
FIN_DU_TEXTE
La redirection par tube et l'emploi de l'expression "$(xxx)" ont déjà été décrits dans la partie "Commandes composées".
Contrairement au DOS qui ne connaît que les variables d'environnement, les shells d'Unix font la distinction entre variables simples et variables d'environnement.
La différence entre les deux est que seules les variables d'environnement sont transmises aux programmes lancés depuis le shell (exception : lorsqu'on utilise le tube ou les parenthèses dans une commande composée, toutes les variables sont communiquées aux sous-shells qui sont lancés implicitement - par contre, ce qui suit reste valable).
La modification d'une variable n'est perçue que par le shell qui la modifie et par ses descendants (c'est-à-dire les commandes qu'il exécute) lorsque c'est une variable d'environnement.
Il s'ensuit qu'un script ne pourra jamais modifier les variables du shell courant, sauf s'il est appelé avec la commande source (voir plus haut "Invocation d'un script").
En Bourne-shell, définir une variable se fait par la commande : variable="valeur". Il est important que valeur soit spécifiée entre guillemets ou apostrophes, et qu'il n'y ait d'espaces ni avant ni après le signe '='. Si valeur est absente, la variable est créée mais contient une chaîne vide.
L'utilisation d'une variable se fait grâce à l'expression $variable ou ${variable}.
La deuxième notation est nécessaire si la variable est suivie d'un texte qui pourrait être interprété comme faisant partie du nom de la variable.
Exemple :
|
luser@localhost$ jour=10; mois=11; an=1997; heures=19; minutes=30 luser@localhost$ echo "Nous sommes le $jour/$mois/$an" Nous sommes le 10/11/1997 luser@localhost$ echo "Il est ${heures}h ${minutes}mn" Il est 19h 30mn |
La variable $# donne le nombre de paramètres accompagnant l'appel du shell-script.
Les variables $@ et $* donnent l'ensemble des paramètres. La différence entre les deux termes ne s'observe que lorsqu'ils sont donnés entre guillemets. En effet, "$*" correspond à une seule valeur contenant tous les paramètres alors que "$@" correspond à autant de valeurs qu'il y a de paramètres.
On peut accéder à chaque paramètre en spécifiant son numéro après le signe $. Si le numéro tient sur deux chiffres ou plus, il doit être donné entre accolades.
Exemples :
$1, ..., $9, ${10}, ${11}, ...\ Le paramètre $0 correspond au nom complet (avec le chemin) du shell- script.
La commande "shift N" élimine les N premiers paramètres de la liste des paramètres (N ne doit pas être supérieur au nombre de paramètres). La variable $# est diminuée d'autant.
Après une commande shift, les paramètres sont donc décalés, c'est à dire que $1 prend la valeur de $(N1)+, $2 prend la valeur de $(N2)+, etc...
Exemple :
#! /bin/sh
#
# params
#
|
# Shell-script de mise en application des paramètres d'un script.
# Affiche l'ensemble des paramètres passés au script. echo "Vous avez lancé le shell-script $0" echo "Vous lui avez fourni $# paramètres qui sont: $*" echo "" echo "Liste des paramètres :" echo "----------------------" numParam=1 for parametre in "$@"; do echo "Paramètre $numParam = $parametre" let $[numParam += 1] done echo "" echo -n "Après la commande 'shift $#', " shift $# echo "il reste $# paramètres" Test : luser@localhost$ ./params A BC DEF "GH IJ" Vous avez lancé le shell-script en lui fournissant les 4 paramètres qui sont: A BC DEF GHIJ: luser@localhost$./params A BC DEF GHIJ Liste des paramètres: --------------------- Paramètre 1 = A Paramètre 2 = BC Paramètre 3 = DEF Paramètre 4 = GH IJ Après la commande 'shift 4', il reste 0 paramètres luser@localhost$ |
Le shell permet d'effectuer des calculs mathématiques mais uniquement sur des entiers. Il y a deux syntaxes possibles :
let $[ expression mathématique ]
let $(( expression mathématique ))
L'expression mathématique peut faire intervenir n'importe quelle variable (pas forcément précédée du signe $) ainsi que n'importe quel nombre entier décimal (219), hexadécimal (0xDB ou 16#DB), octal (0333 ou 8#333) ou binaire (2#011011011). Tous les opérateurs du langage C sont autorisés (+, -, *, %, ||, >>, =, +=, ^=, ==, !=, etc...), y compris les parenthèses.
On peut aussi utiliser la formulation "commande $[ expression mathématique ]". Dans ce cas, l'expression mathématique est remplacée par sa valeur puis la commande est exécutée.
|
Exemple :
luser@localhost$ echo $[ b % a ] 3 luser@localhost$ echo $[ a != 0 ] 1 luser@localhost$ echo $[ b > 20 ] 0 luser@localhost$ let $[ c = ( ( b + a ) << 4 ) & 0xFF ] luser@localhost$ echo $c 144 luser@localhost$ |
La condition d'exécution des structures conditionnelles qui suivent est qu'une commande aboutisse, c'est à dire que sa valeur de retour soit 0.
La commande qui sert de condition peut être une commande composée, en particulier on utilise souvent une formule du type "commande1 && commande2" ou "commande1 || commande2".
La condition peut être inversée si on fait précéder la commande d'un point d'exclamation.
Donc " ! commande" signifie que la condition est vraie si la commande échoue.
Attention, le point d'exclamation s'applique uniquement à la commande qui le suit ; pour qu'il s'applique à une commande composée, il faut l'encadrer avec des accolades (ou des parenthèses).
|
Exemples :
if commande; then echo "La commande a fonctionné"; fi if ! commande; then echo "La commande a échoué"; fi if commande1 && ! commande2; then \\ echo "commande1 a fonctionné mais pas commande2"; fi if ! { commande1 || commande2; } ; then \ echo "Ni commande1 ni commande2 n'ont fonctionné"; fi |
La condition d'exécution devant être une commande, les tests s'effectuent par l'intermédiaire de la commande "test expression" qui peut être abrégée par la formule "[expression ]".
|
Les tests possibles peuvent porter sur des entiers, des chaînes de caractères ou des fichiers/répertoires.
Tests sur les fichiers (et sur les 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 lisible. "-w fichier" : vrai si le fichier/répertoire est modifiable. "-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. |
|
Il y a erreur si ce ne sont pas des entiers autour de l'opérateur.
"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. |
|
Encadrer la chaîne 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. |
Lorsqu'un test doit être inversé ou lorsque plusieurs tests doivent être combinés par des ET et des OU, on a le choix entre deux notations. La première a été présentée dans la partie précédente ("Les conditions") ; elle est préférable car elle est plus lisible. La deuxième fait partie de la syntaxe de la commande test :
|
"NON expr" se traduit par "test ! expr" ou "[ ! expr ]".
"expr1 OU expr2" se traduit par "test expr1 -o expr2" ou "[ expr1 -o expr2 ]". "expr1 ET expr2" se traduit par "test expr1 -a expr2" ou "[ expr1 -a expr2 ]". |
En Bourne-shell, la structure algorithmique se traduit par :
Si commande1 aboutit, alors if commande1; then action1
Sinon si commande2 aboutit, alors elif commande2; then action2
Sinon else action3 FinSi fi
Bien sûr, chacune des parties "sinon si" et "sinon" est optionnelle.
D'autre part les actions à effectuer peuvent être composées de plusieurs commandes sur une ou plusieurs lignes.
A l'extrême, on peut tout placer sur une seule ligne (bien respecter les points-virgules) mais c'est fortement déconseillé car cela nuit à la lisibilité :
if commande1; then action1; elif commande2; then action2; else action3; fi
|
Exemple :
#! /bin/sh # # signe # # Shell-script de mise en application de l'instruction if...then...else. # Affiche le signe d'un nombre et de son opposé. # # Saisie de n # echo -n "Entrez un nombre: " read n # # Test du signe de n # if test $n -lt 0; then # n < 0 ? echo "Le nombre $n est négatif" elif test $n -gt 0; then # n > 0 ? echo "Le nombre $n est positif" else # n = 0 echo "Le nombre $n est nul" fi # # Changement du signe de n # let $[ n = -n ] echo "Le nombre choisi devient $n" # # Test du signe de n (autre méthode) # if [ $n -le 0 ]; then # n <= 0 ? if [ ! $n -eq 0 ]; then # n != 0 ? C'est à dire n < 0 ? echo "Le nombre $n est négatif" else # n = 0 echo "Le nombre $n est nul" fi else # n > 0 echo "Le nombre $n est positif" fi Test : luser@localhost$ ./signe Entrez un nombre: 3 Le nombre 3 est positif Le nombre choisi devient -3 Le nombre -3 est négatif luser@localhost$ ./signe Entrez un nombre: 0 Le nombre 0 est nul Le nombre choisi devient 0 Le nombre 0 est nul luser@localhost$ |
Cette structure n'existe pas en Bourne-shell. Attention aux confusions, le mot-clé until est lié à une structure TantQue, comme on le voit dans ce qui suit.
En Bourne-shell, la structure algorithmique se traduit par :
TantQue commande aboutit while commande; do
action action
FinTQ done
TantQue commande échoue until commande; do
action action
FinTQ done
L'action à effectuer peut être composée de plusieurs commandes sur une ou plusieurs lignes.
A l'extrême, on peut tout placer sur une seule ligne (bien respecter les points-virgules) mais c'est fortement déconseillé car cela nuit à la lisibilité :
while commande; do action; done
until commande; do action; done
|
Exemple pour while :
#! /bin/sh # # factorielle # # Shell-script de mise en application de l'instruction while. # Affiche la factorielle du nombre donné en paramètre. if [ $# -ne 1 ] || [ $1 -lt 0 ]; then echo "Usage: factorielle n (avec n >= 0)" 1>&2 else resultat=1 n=$1 while [ $n -gt 1 ]; do let $[ resultat *= n] let $[ n -= 1] done echo "$resultat" fi Test: luser@localhost$ factorielle 3 6 luser@localhost$ factorielle 6 720 luser@localhost$ factorielle $(factorielle 3) 720 Exemple : pour until #! /bin/sh # # testfact # # Shell-script de mise en application de l'instruction until. # Teste le shell-script de calcul de factorielles. n=0 until [ $n -eq 14 ]; do resultat=$(factorielle $n) echo "$n! = $resultat" let $[ n += 1 ] done Test: luser@localhost$ ./testfact 0! = 1 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880 10! = 3628800 11! = 39916800 12! = 479001600 13! = 1932053504 luser@localhost$ |
Pour chaque élément de l'ensemble (element1, element2, ..., elementN) action sur element FinPour
En Bourne-shell, la structure algorithmique se traduit par :
for element in element1 element2 ... elementN; do
action $element
done
L'action à effectuer peut être composée de plusieurs commandes sur une ou plusieurs lignes.
A l'extrême, on peut tout placer sur une seule ligne (bien respecter les points-virgules) mais c'est fortement déconseillé car cela nuit à la lisibilité :
|
for element in element1 element2 ... elementN; do action $element; done Exemple : #! /bin/sh # # fic_ou_rep # # Shell-script de mise en application de l'instruction for. # Affiche le type (fichier ou répertoire) de chaque paramètre. for param in "$@"; do # Pour chaque paramètre... if [ -f "$param" ]; then # C'est un fichier? echo "$param est un fichier." elif [ -d "$param" ]; then # C'est un répertoire? echo "$param est un répertoire." elif ! [ -e "$param" ]; then # N'existe pas echo "$param n'existe pas." else # C'est autre chose? echo "$param n'est ni un fichier, ni un répertoire." fi done Test : luser@localhost$ ./fic_ou_rep XXX /etc "./un rep/" /etc/hosts "./un rep/un fic" /dev/lp0 XXX n'existe pas. /etc est un répertoire. ./un rep/ est un répertoire . /etc/hosts est un fichier. ./un rep/un fic est un fichier . /dev/lp0 n'est ni un fichier, ni un répertoire. luser@localhost$ |
En Bourne-shell, la structure algorithmique se traduit par :
Selon valeur case valeur in cas X : X )
action1 action1;;
cas Y :
cas Z : Y $|$ Z )
action2 action2;;
defaut : * )
action3 action3;;
FinSelon esac
Les actions à effectuer peuvent être composées de plusieurs commandes sur une ou plusieurs lignes. Pour chaque cas, la série de commandes à exécuter doit être terminée par deux points-virgules que l'on placera de préférence sur une seule ligne.
Les cas à tester peuvent employer les caractères génériques autorisés pour les fichiers.
Par exemple, les cas "a ? ? ?b", "A*B*C" et [a-z]*[0-9] sont tout à fait valides. Si toutefois un caractère fait partie d'un cas à tester, il faudra l'encadrer par des guillemets pour qu'il ne soit pas interprété.
|
Exemple : #! /bin/sh # # question # # Shell-script de mise en application de l'instruction case. # Pose une question et attend une réponse par oui ou non. # La valeur retournée est 0 pour oui et 1 pour non. retour=X while [ "$retour" = "X" ]; do echo -n "On continue (O/N) ? " read reponse case "$reponse" in o* | O* ) retour=0 ;; [nN]* ) retour=1 ;; "?"* ) echo "Il n'y a pas d'aide disponible" ;; * ) echo "Erreur : entrez [O]ui ou [N]on." ;; esac echo "" done exit $retour Test : luser@localhost$ question ; echo "Retour = $?" On continue (O/N) ? bof Erreur: entrez [O]ui ou [N]on . On continue (O/N) ? oui, je veux bien Retour = 0 luser@localhost$ question ; echo "Retour = $?" On continue (O/N) ? ??? Il n'y a pas d'aide disponible On continue (O/N) ? Non, merci Retour = 1 luser@localhost$ |
Grâce à la commande trap, on peut déclencher une action sur un événement particulier.
La contrainte est que cet événement soit un signal que l'on peut intercepter (faire "trap -l" pour en avoir la liste et "man 7 signal" pour obtenir des détails supplémentaires sur ces signaux).
En Bourne-shell, la structure algorithmique se traduit par :
Lorsque le signal SIGNAL survient trap "action" SIGNAL action FinLorsque
L'action peut être une commande composée. Dès qu'elle ne se limite pas à un seul mot, elle doit être précisée entre guillemets. Les guillemets et apostrophes situés à l'intérieur doivent être précédés par un anti-slash. Bien sûr, plusieurs signaux peuvent être précisés en une seule fois.
La commande trap utilisée seule donne la liste des actions exécutées pour chaque signal.
La commande "trap SIGNAL" annule l'action à exécuter à l'arrivée du signal SIGNAL.
|
Exemple :
#! /bin/sh # # exTrap # # Shell-script de mise en application de l'instruction case. trap "echo Le script s\'est terminé" EXIT trap "echo Vous avez appuyé sur Ctrl-C" SIGINT trap "echo Vous avez fait: kill $$" SIGTERM trap "echo J\'ai été stoppé et je continue" SIGCONT trap "echo J\'ai rec?u SIGUSR1 ou SIGUSR2" SIGUSR1 SIGUSR2 echo "Processus $$: J'attend un signal..." # # Compte à rebours # i=10 while [ $i -gt 0 ]; do echo -n "$i " sleep 1 let $[ i -= 1 ] done echo "0" Test : luser@localhost$ ./exTrap Processus 1658: J'attend un signal... 10 9 Vous avez appuyé sur Ctrl-C 8 7 [1]+ Stopped exTrap luser@localhost$ kill -SIGUSR1 1658 luser@localhost$ fg exTrap J'ai reçu SIGUSR1 ou SIGUSR2 J'ai été stoppé et je continue 6 5 4 [1]+ Stopped exTrap luser@localhost$ kill -SIGUSR2 1658 luser@localhost$ kill 1658 luser@localhost$ fg exTrap J'ai reçu SIGUSR1 ou SIGUSR2 Vous avez fait: kill 1658 J'ai été stoppé et je continue 3 2 1 0 Le script s'est terminé luser@localhost$ |
Le Bourne-shell offre la possibilité de définir ses propres fonctions. Bien qu'elles soient internes à un shell, elles s'emploient comme un script externe. Mais leur appel ne provoque pas le lancement d'un sous-shell, donc une fonction a accès à toutes les variables, pas seulement celles d'environnement, et leur modification reste prise en compte lorsque la fonction se termine.
Syntaxe
function maFonction()
{
local var1
local var2="valeur"
commande1
commande2
return val;
}
Le mot-clé "local" permet de définir des variables locales à la fonction.
La dernière commande doit être terminée par un point-virgule.
On accède aux paramètres d'une fonction comme à ceux d'un script : grâce aux variables $*, $@, $#, $1, $2, ... qui sont temporairement modifiées pendant toute la durée de la fonction. En revanche, $0 ne change pas.
Le retour d'une valeur s'effectue grâce au mot-clé return. Si return n'est pas employé, la valeur de retour est celle de la dernière commande exécutée.
Attention, l'emploi de la commande exit termine non seulement la fonction mais aussi le script.
Une fonction peut être récursive, c'est àdire qu'elle peut s'appeler elle-même.
Une fois définie, une fonction apparaît dans la liste des variables. On peut l'exporter vers les autres shells grâce à la commande "export -f maFonction".
|
Exemple :
#! /bin/sh # # signe2 # # Shell-script de mise en application des fonctions. # Affiche le signe d'un nombre et de son carré. # # # carré(nombre) # # Retourne le carré du nombre donné en paramètre. # # Paramètres: $1 -> Le nombre dont on veut le carré # function carré() { return $[ $1 * $1 ] } # # # affSigne(nombre) # # Affiche le signe du nombre donné en paramètre. # # Paramètres: $1 -> Le nombre dont on teste le signe. # function affSigne() { local signe if [ $n -lt 0 ]; then # n < 0 ? signe=négatif elif [ $n -gt 0 ]; then # n > 0 ? signe=positif else # n = 0 signe=nul fi echo "Le nombre $1 est $signe" } # # # Programme principal # echo -n "Entrez un nombre: " read n # Saisie de n affSigne $n # Affichage du signe de n carré $n # Calcul du carré de n n=$? # Récupération du résultat echo "Le carré du nombre choisi est $n" affSigne $n # Affichage du signe de n Test : luser@localhost$ ./signe2 Entrez un nombre: -5 Le nombre -5 est négatif Le carré du nombre choisi est 25 Le nombre 25 est positif luser@localhost$ ./signe2 Entrez un nombre: 0 Le nombre 0 est nul Le carré du nombre choisi est 0 Le nombre 0 est nul |