Atelier Systèmes d’Exploitation
Chapitre III : La programmation de base en Shell
Amine DHRAIEF 1 [ère] année Licence LFIG ESEN, Université De La Manouba
Portées et attributs des variables
Les variables employées par le shell sont caractérisées par leur portée,
c’est-à-dire par une certaine visibilité dans les sous processus, fonctions, etc.
Une variable qui est simplement définie avec une commande variable=valeur, sans autres précisions, est accessible dans l’ensemble du processus en cours.
Cela comprend les fonctions que l’on peut invoquer
12/11/17 Atelier S.E 2
Portées et attributs des variables
Portées et attributs des variables
##### La fonction a accès au contenu de la variable en lecture, mais aussi en écriture
Portées et attributs des variables
###### Une fonction peut aussi définir une variable qui n’existait pas jusqu’alors, et qui sera désormais accessible par le reste du processus, même après la fin de la fonction.
###### Pour observer ce phénomène, il faut configurer le shell avec la commande set -u pour qu’il fournisse un message d’erreur si on tente d’accéder à une variable indéfinie.
12/11/17 Atelier S.E 5
Portées et attributs des variables
12/11/17 Atelier S.E 6
Portées et attributs des variables
Portées et attributs des variables Restriction de portée
La seule restriction possible de visibilité concerne les fonctions. Il est possible d’y déclarer des variables locales qui ne seront pas accessibles dans le processus supérieur. Elles seront en revanche parfaitement disponibles pour les sous-fonctions éventuellement invoquées.
Lorsqu’on déclare une variable avec le mot-clé local, et qu’elle existait déjà au niveau supérieur du script, la nouvelle instance masque la précédente jusqu’au retour de la fonction.
12/11/17 Atelier S.E 8
Portées et attributs des variables
Restriction de portée
Portées et attributs des variables
Restriction de portée
12/11/17 Atelier S.E 10
Portées et attributs des variables Extension de portée – Environnement
Nous avons remarqué que, lorsqu’un processus lance un script par l’intermédiaire d’un appel ./script, il ne lui transmet pas les variables définies d’une manière courante.
Ces variables, en effet, sont placées en mémoire dans une zone de travail du shell, qui n’est pas copiée lorsqu’un nouveau processus démarre pour exécuter le script.
Il est parfois indispensable de transmettre des données à ce nouveau script et il faut donc trouver un moyen de placer les variables dans une zone de mémoire qui sera copiée dans l’espace du nouveau processus.
Cette zone existe : c’est l’environnement du processus. Pour qu’une variable y soit disponible, il faut qu’elle soit marquée comme exportable. On obtient cela tout simplement grâce à la commande interne export .
12/11/17 Atelier S.E 11
Portées et attributs des variables Extension de portée – Environnement
12/11/17 Atelier S.E 12
Portées et attributs des variables Extension de portée – Environnement
La commande export marque les variables transmises en argument comme exportables (par exemple, export var1 var2 ), mais peut aussi regrouper une ou plusieurs affectations de variables sur la même ligne, par exemple.
export -p affiche la liste des éléments marqués comme exportables.
12/11/17 Atelier S.E 13
Portées et attributs des variables Extension de portée – Environnement
L’option export -n enlève l’attribut « exportable » d’une variable. Elle n’est en revanche pas supprimée pour autant ; elle sera seulement indisponible dans les processus fils
12/11/17 Atelier S.E 14
Portées et attributs des variables
Attributs des variables
##### Nous avons déjà vu qu’une variable pouvait être dotée d’un attribut « exportable » qui permet de la placer dans une zone mémoire qui sera copiée dans l’environnement de travail du processus.
##### Deux autres attributs sont également disponibles, que l’on peut activer à l’aide de la commande declare de Bash
12/11/17 Atelier S.E 15
Portées et attributs des variables Attributs des variables – La commande declare
En plus de la forme variable=valeur, le Bash possède une commande générale de définition de variable :
declare [+/ option] [ p] ]
option affecte l’attribut à variable
+option enlève l’attribut à variable
L’option –p, exclusive des autres options, permet d’afficher les variables et leur valeur.
-a variable est de type tableau,
-i variable est de type numérique entier,
-r variable en lecture seule,
-x variable exportée (variable placée dans l’environnement)
12/11/17 Atelier S.E 16
Portées et attributs des variables Attributs des variables : Variable arithmétique
On peut indiquer avec declare -i que le contenu d’une variable sera strictement arithmétique.
Lors de l’affectation d’une valeur à cette variable, le shell procédera systématiquement à une phase d’évaluation arithmétique exactement semblable à ce qu’on obtient avec l’opérateur $(( )) .
En fait, on peut considérer que, si une variable A est déclarée arithmétique, toute affectation du type A=xxx sera évaluée sous la forme A=$((xxx)) .
12/11/17 Atelier S.E 17
Portées et attributs des variables Attributs des variables : Variable arithmétique
12/11/17 Atelier S.E 18
Portées et attributs des variables Attributs des variables : Variable arithmétique
##### Si on veut insérer des espaces dans la formule, il faut la regrouper en un seul bloc au moyen de guillemets
Publicité
12/11/17 Atelier S.E 19
Portées et attributs des variables Attributs des variables : Variable arithmétique
Lors de l’affectation d’une variable arithmétique, le contenu des variables éventuellement contenues dans l’expression est évalué sous forme arithmétique
12/11/17 Atelier S.E 20
Virgule flottante
Bash ne permet pas d’effectuer de calculs en virgule flottante.
Certaines version de Ksh le permettent, mais la portabilité est amoindrie. Toutefois, les scripts shell peuvent quand même bénéficier de l’arithmétique des nombres réels grâce à un outil standard nommé bc .
Cet outil peut être utilisé de manière interactive (comme une calculatrice) ou dans un script.
12/11/17 Atelier S.E 21
Virgule flottante : exemple
Dans la bibliothèque étendue de bc (accessible via son option
l en ligne de commande), la fonction a(x) renvoie l’arc tangente de x .
Voici un exemple interactif :
12/11/17 Atelier S.E 22
Virgule flottante : exemple
Et voici un moyen d’incorporer un appel à bc dans un script shell :
12/11/17 Atelier S.E 23
Portées et attributs des variables Attributs des variables : Variable arithmétique
Une valeur non arithmétique est bien considérée comme un zéro
Les commandes declare -i seules affichent la liste des variables arithmétiques. La commande declare +i var, supprime l’attribut arithmétique d’une variable.
12/11/17 Atelier S.E 24
Portées et attributs des variables Attributs des variables : Variable en lecture seule
###### L’option -r des commandes declare permet de figer une variable afin qu’elle ne soit plus accessible qu’en lecture (ce qui en fait finalement une constante et non plus une variable !).
###### Cela ne concerne toutefois que le processus en cours ; si la variable est exportée vers un shell fils, ce dernier pourra la modifier dans son propre environnement.
12/11/17 Atelier S.E 25
Portées et attributs des variables Attributs des variables : Variable en lecture seule
Paramètres positionnels
##### Les paramètres positionnels sont utilisés pour accéder aux informations qui sont fournies sur la ligne de commande lors de l’invocation d’un script, mais aussi aux arguments transmis à une fonction.
##### Les arguments sont placés dans des paramètres qui peuvent être consultés avec la syntaxe $1, $2, $3, etc.
12/11/17 Atelier S.E 27
Paramètres positionnels
###### Le premier argument transmis est accessible en lisant $1, le deuxième dans $2, et ainsi de suite.
###### Pour consulter le contenu d’un paramètre qui comporte plus d’un chiffre, il faut l’encadrer par des accolades ; ainsi, ${10} correspond bien au contenu du dixième argument, tandis que $10 est une chaîne constituée de la valeur du premier argument, suivie d’un zéro.
12/11/17 Atelier S.E 28
Paramètres positionnels
12/11/17 Atelier S.E 29
Paramètres positionnels
12/11/17 Atelier S.E 30
Paramètres positionnels
En plus des variables 1, 2, ..., 9, le shell prédéfinit des variables facilitant la programmation.
| 0 | contient le nom sous lequel le script est invoqué, |
|---|---|
| # | contient le nombre de paramètres passés en argument, |
| * | contient la liste des paramètres passés en argument |
| ? | contient le code de retour de la dernière commande exécutée, |
| $ | contient le numéro de process (PID) du shell (décimal). |
| @ | contient l'ensemble des arguments, un argument par paramètre |
12/11/17 Atelier S.E 31
Action par défaut
Lorsqu’un script fonde son comportement sur des variables qui sont fournies par l’utilisateur, il est important de pouvoir configurer une action par défaut, dans le cas où la variable n’aurait pas été remplie.
L’expression ${variable:-valeur} prend la valeur indiquée à droite du modificateur :- si la variable n’existe pas, ou si elle est vide. Cela nous permet de fournir une valeur par défaut.
Naturellement, si la variable existe et est non vide, l’expression
renvoie son contenu :
12/11/17 Atelier S.E 32
Action par défaut
12/11/17 Atelier S.E 33
Action par défaut
L’emploi systématique de valeurs par défaut en début de script permet d’améliorer la robustesse du programme, et de le rendre plus souple, plus facile à configurer par l’utilisateur. Le contenu même de la variable n’est pas modifié. Toutefois, il est des cas où cela serait préférable.
La construction $ {variable:=valeur} peut être utilisée à cet effet. Si la variable n’existe pas ou si elle est vide, elle est alors remplie avec la valeur. Ensuite, dans tous les cas, le contenu de la variable est renvoyé.
12/11/17 Atelier S.E 34
Action par défaut
12/11/17 Atelier S.E 35
Les Tableaux
Nous n’avons évoqué, jusqu’à présent, que des variables scalaires. Les shells récents permettent toutefois de manipuler des tableaux qui contiennent autant de données qu’on le souhaite (la seule limitation étant celle de la mémoire du système).
La notation : tableau =valeur a pour effet de définir un emplacement mémoire pour la i [ème] case du tableau, et de la remplir avec la valeur voulue.
La consultation se fera ainsi : ${tableau }
12/11/17 Atelier S.E 36
Les Tableaux
Les index des tableaux sont numérotés à partir de zéro. En fait, ${tableau[0]} est identique à $tableau .
Cela signifie donc que n’importe quelle variable peut être considérée comme le rang zéro d’un tableau qui ne contient qu’une case.
On peut aussi ajouter autant de membres qu’on le désire à une variable existante
12/11/17 Atelier S.E 37
Les Tableaux
12/11/17 Atelier S.E 38
Publicité
Les Tableaux
##### La commande declare -a permet de déclarer une variable comme un tableau
12/11/17 Atelier S.E 39
Les Tableaux
Les notations ${table[*]} et ${table[@]} fournissent une liste de tous les membres du tableau.
Placées entre guillemets, ces deux notations présentent
les mêmes différences que $* et $@ pour les paramètres positionnels.
- ème ${#table } fournit la longueur du i membre du tableau, alors que ${#table[*]}, comme $ {#table[@]}, fournissent le nombre de membres
12/11/17 Atelier S.E 40
Les Tableaux
12/11/17 Atelier S.E 41
Les instructions de lecture et d’écriture
##### Ces instructions permettent de créer des fichiers de commandes interactifs par l’instauration d’un dialogue sous forme de questions/réponses.
##### La question est posée par l’ordre echo et la réponse est obtenue par l’ordre read à partir du clavier.
12/11/17 Atelier S.E 42
Les instructions de lecture et d’écriture
read variable1 variable2... variable_n
read lit une ligne de texte à partir du clavier, découpe la ligne en mots et attribue aux variables variable1 à variablen ces différents mots.
S’il y a plus de mots que de variables, la dernière variable se verra affecter le reste de la ligne.
12/11/17 Atelier S.E 43
Les instructions de lecture et d’écriture
12/11/17 Atelier S.E 44
Les structures de contrôle
##### Le shell possède des structures de contrôle telles qu’il en existe dans les langages de programmation d’usage général :
instructions conditionnelles (if.. then.. else, test,
case),
itérations bornées,
itérations non bornées.
12/11/17 Atelier S.E 45
Les instructions conditionnelles
12/11/17 Atelier S.E 46
Les structures de contrôle: Les instructions conditionnelles
##### Pour la programmation des actions conditionnelles, nous disposons de trois outils :
l’instruction if,
la commande test qui la complète,
l’instruction case
12/11/17 Atelier S.E 47
Les instructions conditionnelles : if
Elle présente trois variantes qui correspondent aux structures sélectives à une, deux ou n alternatives.
La sélection à une alternative : if... then... fi
if commande1
then commandes
fi
Les commandes sont exécutées si la condition commande1 un code retour nul ( $? = 0 )
12/11/17 Atelier S.E 48
Les instructions conditionnelles : if
Il faut nécessairement séparer la condition indiquée après un if du mot-clé then .
Pour cela, on insère généralement un retour à la ligne comme nous l’avons fait ci-dessus, mais on peut également utiliser un point-virgule à cet effet :
if commande ; then commande fi
12/11/17 Atelier S.E 49
Les instructions conditionnelles : if
La sélection à deux alternatives : if... then... else... fi
if commande then commandes1 else commandes2 fi
Les commandes commandes1 sont exécutées si la commande_condition commande renvoie un code retour nul, sinon ce sont les commandes2 qui sont exécutées.
12/11/17 Atelier S.E 50
Les instructions conditionnelles : if
La sélection à n alternatives : if... then.... elif... then... fi
if commande1
then commandes1 elif commande2
then commandes2 elif commande3
then commandes3 ... else
commandes0 fi
12/11/17 Atelier S.E 51
Les instructions conditionnelles : if
12/11/17 Atelier S.E 52
Les instructions conditionnelles : test
Elle constitue l’indispensable complément de l’instruction if. Elle permet très simplement :
de reconnaître les caractéristiques des fichiers et des répertoires,
de comparer des chaînes de caractères,
Publicité
de comparer algébriquement des nombres.
Cette commande existe sous deux syntaxes différentes :
test expression
ou
[ expression ]
12/11/17 Atelier S.E 53
Les instructions conditionnelles : test
La commande test répond à l’interrogation formulée dans expression, par un code de retour nul en cas de réponse positive et différent de zéro sinon.
La deuxième forme est plus fréquemment rencontrée et donne lieu à des programmes du type : if [ expression ]
then commandes
fi
Dans [ expression ], ne pas oublier le caractère espace entre [ et expres sion et entre expression et ]. Si then est sur la même ligne, il doit être séparé du ] par un espace et un caractère
12/11/17 Atelier S.E 54
12/11/17 Atelier S.E 55
Les instructions conditionnelles : case
L’instruction case est une instruction très puissante et très commode pour effectuer un choix multiple dans un fichier de commandes.
case chaine in
motif1) commandes 1 ;;
motif2) commandes 2 ;;
....
....
motifn) commandes n ;;
esac
12/11/17 Atelier S.E 56
Les instructions conditionnelles : case
Le shell recherche, parmi les différentes chaînes de caractères motif1, motif2,..., motifn proposées, la première qui correspond à chaine et il exécute les commandes correspondantes.
Un double point virgule (;;) termine chaque choix.
La chaine dans un case peut prendre diverses formes :
un chiffre,
une lettre ou un mot,
des caractères spéciaux du shell,
une combinaisons de ces éléments.
La chaine peut être lue, passée en paramètre ou être le résultat d’une commande
exécutée avec l’opérateur backquote ou $( ).
12/11/17 Atelier S.E 57
Les instructions conditionnelles
En ce qui concerne les comparaisons de chaînes, il est recommandé de toujours encadrer le nom des variables par des guillemets, afin d’éviter les erreurs, susceptibles de se produire si une chaîne est vide
12/11/17 Atelier S.E 58
Les instructions conditionnelles
On peut associer plusieurs conditions avec les opérateurs suivants :
Ces options rendant les expressions difficilement lisibles, il est préférable de juxtaposer directement plusieurs commandes de test à l’aide des symboles && et ||
12/11/17 Atelier S.E 59
Les instructions conditionnelles
12/11/17 Atelier S.E 60
Exemple case
L’exemple suivant – que l’on peut considérer comme une portion de script d’installation d’une application sous Linux – va invoquer l’utilitaire uname pour connaître le numéro de version du noyau en cours d’utilisation.
En fonction du résultat, il s’arrêtera ou poursuivra l’exécution, éventuellement après avoir interrogé l’utilisateur.
Afin de pouvoir « tricher » et tester les différents cas, on n’invoque l’utilitaire uname que si aucun argument n’a été indiqué sur la ligne de commande, sinon on emploie le premier transmis en guise de numéro de version
12/11/17 Atelier S.E 61
Exemple case
12/11/17 Atelier S.E 62
Exemple case
12/11/17 Atelier S.E 63
Les itérations
12/11/17 Atelier S.E 64
Itération bornée : La boucle for
##### La présence des instructions itératives dans le shell en fait un langage de programmation complet et puissant.
##### Le shell dispose de trois structures itératives :
for
while
until
12/11/17 Atelier S.E 65
Itération bornée : La boucle for
12/11/17 Atelier S.E 66
Itération bornée : La boucle for
Pour chacune des trois formes, les commandes placées entre do et done sont exécutées pour chaque valeur prise par la variable du shell variable.
Ce qui change c’est l’endroit où variable prend ses valeurs.
Pour la forme 1, les valeurs de variable sont les chaines de
chaine1 à chainen.
Pour la forme 2, variable prend ses valeurs dans la liste des
Publicité
paramètres du script.
Pour la forme 3, la liste des fichiers du répertoire constitue les
valeurs prises par variable.
12/11/17 Atelier S.E 67
Itération bornée : La boucle for Exemple 1
12/11/17 Atelier S.E 68
Itération bornée : La boucle for Exemple 2
12/11/17 Atelier S.E 69
Itération bornée : La boucle for Exemple 3
12/11/17 Atelier S.E 70
Itération bornée : La boucle for Exemple 4
12/11/17 Atelier S.E 71
Itérations non bornées : while et until
Les commandes commandebeta sont exécutées tant que (while) ou jusqu’à ce que (until) la commande commandealpha retourne un code nul (la condition est vraie).
12/11/17 Atelier S.E 72
Itérations non bornées : while et until Exemple 1
12/11/17 Atelier S.E 73
Itérations non bornées : while et until Exemple 2
12/11/17 Atelier S.E 74
Exercice I
Écrire un shell script qui écrit sur sa sortie standard les messages suivants :
mon nom est xxx
je suis appele avec yyy arguments
qui sont: 111 222 333 444
(xxx sera remplacé par le nom sous lequel ce shell script aura été invoqué, yyy par
le nombre d’arguments et 111, 222, etc. par les arguments en question).
Quand ce script fonctionnera correctement, invoquez le avec les cinq arguments :
Bienvenue dans le monde Linux
puis avec un seul argument contenant la chaîne de caractères : Bienvenue dans le
monde Linux
12/11/17 Atelier S.E 75
Correction Exercice I
12/11/17 Atelier S.E 76
Exercice II
##### Créer un script permettant d'afficher la liste des fichiers du répertoire /etc accessibles en lecture
12/11/17 Atelier S.E 77
Correction Exercice II
12/11/17 Atelier S.E 78
Exercice III
##### Ecrire un script qui émule le fonctionnement d'un shell
Il lit la saisie d'une commande shell de l'utilisateur
Si la la saisie est non vide il exécute la commande
12/11/17 Atelier S.E 79
Évaluation explicite d’une expression
L’une des grosses différences entre les langages compilés et les langages interprétés est qu’il est généralement possible, avec ces derniers, de construire de toutes pièces une expression, puis de l’évaluer comme s’il s’agissait d’une partie du programme en cours.
Le shell propose une fonction nommée eval qui permet d’obtenir ce comportement. Elle sert à réclamer au shell une seconde évaluation des arguments qui lui sont transmis.
12/11/17 Atelier S.E 80
Évaluation explicite d’une expression
##### Pour bien comprendre ce que cela signifie, il nous faut procéder par étapes successives.
Tout d’abord, on définit une variable A, et une
variable B contenant une chaîne de caractères dans laquelle on trouve l’expression $A .
12/11/17 Atelier S.E 81
Évaluation explicite d’une expression
Lors de l’affectation de B, nous avons protégé le caractère $ pour qu’il ne soit pas vu comme une consultation du contenu de A .
Examinons à présent ce qui se passe lorsqu’on invoque eval avant echo :
12/11/17 Atelier S.E 82
Évaluation explicite d’une expression
En fait, lorsque le shell interprète la ligne « eval echo $B », il remplace $B par le contenu de la variable, puis invoque eval en lui passant en arguments « echo », « A », « = » et « $A ».
Le travail d’ eval consiste alors à regrouper ses arguments en une seule ligne « echo A = $A » qu’il fait réévaluer par le shell.
Celui-ci remplace alors $A par son contenu et affiche le
résultat attendu.
12/11/17 Atelier S.E 83
Correction Exercice III
Le petit script suivant est une représentation très simplifiée de la boucle d’interprétation du shell.
Il lit la saisie de l’utilisateur dans sa variable ligne et en demande l’évaluation au shell. Si la saisie est vide, le script se termine.
12/11/17 Atelier S.E 84