IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Introduction à la programmation en Bash


précédentsommairesuivant

II. Substitution de paramètres

Dans la terminologie du shell, un paramètre désigne toute entité pouvant contenir une valeur.

Le shell distingue trois classes de paramètres :

  • les variables, identifiées par un nom (Ex : a , PATH)
  • les paramètres de position, identifiés par un numéro (Ex : 0 , 1 , 12)
  • les paramètres spéciaux, identifiés par un caractère spécial (Ex : # , ? , $)

Le mode d’affectation d'une valeur est spécifique à chaque classe de paramètres. Suivant celle-ci, l’affectation sera effectuée par l’utilisateur, par bash ou bien par le système. Par contre, pour obtenir la valeur d'un paramètre, on placera toujours le caractère $ devant sa référence, et cela quelle que soit sa classe.

 
Sélectionnez
$ echo $PATH             => affiche la valeur de la variable PATH
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:.:/home/sanchis/bin
$ echo $$                => affiche la valeur du paramètre spécial $
17286
$

II-1. Variables

Une variable est identifiée par un nom, c'est-à-dire une suite de lettres, de chiffres ou de caractères espace souligné ne commençant pas par un chiffre. Les lettres majuscules et minuscules sont différenciées.

Les variables peuvent être classées en trois groupes :

  • les variables utilisateur (ex : a, valeur)
  • les variables prédéfinies du shell (ex : PS1, PATH, REPLY, IFS)
  • les variables prédéfinies de commandes unix (ex : TERM).

En général, les noms des variables utilisateur sont en lettres minuscules tandis que les noms des variables prédéfinies (du shell ou de commandes unix) sont en majuscules.

L’utilisateur peut affecter une valeur à une variable en utilisant

  • l’opérateur d’affectation =
  • la commande interne read.

II-1-1. Affectation directe

 
Sélectionnez
Syntaxe :       nom=[valeur]   [ nom=[valeur] ... ]

Il est impératif que le nom de la variable, le symbole = et la valeur à affecter ne forment qu’une seule chaîne de caractères.
Plusieurs affectations peuvent être présentes dans la même ligne de commande.

 
Sélectionnez
$ x=coucou       y=bonjour         => la variable x contient la chaîne de caractères coucou
                                   => la variable y contient la chaîne bonjour
$

ATTENTION : les syntaxes d’affectation erronées les plus fréquentes contiennent

  • un ou plusieurs caractères espace entre le nom de la variable et le symbole =.
    Le shell interprète b comme une commande à exécuter ; ne la trouvant pas, il signale une erreur.
 
Sélectionnez
$ b        =coucou
-bash: b: command not found
$
  • un ou plusieurs caractères espace entre le symbole = et la valeur de la variable.
    La chaîne coucou est interprétée comme la commande à exécuter.
 
Sélectionnez
$ y=       coucou
-bash: coucou: command not found
$

Lorsque le shell rencontre la chaîne $x, il la remplace textuellement par la valeur de la variable x, c.-à-d. coucou ; la commande exécutée par bash est : echo x est coucou

 
Sélectionnez
$ echo x est $x
x est coucou
$

Il est important de remarquer que le nom d’un paramètre et la valeur de ce paramètre ne se désignent pas de la même manière.

 
Sélectionnez
$ x=$x$y                     => x : contenant, $x : contenu
$ echo $x
coucoubonjour
$

II-1-2. Affectation par lecture

Elle s’effectue à l'aide de la commande interne read. Celle-ci lit une ligne entière sur l’entrée standard.

 
Sélectionnez
Syntaxe :      read [ var1 ... ]
 
Sélectionnez
$ read a b
bonjour Monsieur             => chaînes saisies par l’utilisateur et enregistrées
                             => respectivement dans les variables a et b
$ echo $b
Monsieur
$

Lorsque la commande interne read est utilisée sans argument, la ligne lue est enregistrée dans la variable prédéfinie du shell REPLY.

 
Sélectionnez
$ read
bonjour tout le monde
$
$ echo $REPLY
bonjour tout le monde
$

L’option –p de read affiche une chaîne d’appel avant d’effectuer la lecture ; la syntaxe à utiliser est :

 
Sélectionnez
read –p chaîne_d_appel [ var ... ]
 
Sélectionnez
$ read -p "Entrez votre prenom : " prenom
Entrez votre prenom : Eric
$ echo $prenom
Eric
$

Remarques sur la commande interne read

  • S’il y a moins de variables que de mots dans la ligne lue, le shell affecte le premier mot à la première variable, le deuxième mot à la deuxième variable, etc., la dernière variable reçoit tous les mots restants.
 
Sélectionnez
$ read a b c
un bon jour coucou
$ echo $a
un
$ echo $c
jour coucou
$
  • S’il y a davantage de variables que de mots dans la ligne lue, chaque variable reçoit un mot et après épuisement de ces derniers, les variables excédentaires sont vides (c.-à-d. initialisées à la valeur null).
 
Sélectionnez
$ read a b
Un
$ echo $a
Un
$ echo $b
                => valeur null
$

Exercice 1 :
Ecrire un programme shell deuxfois qui affiche le message "Entrez un mot : ", lit le mot saisi par l'utilisateur puis affiche ce mot deux fois sur la même ligne.

 
Sélectionnez
$ deuxfois
Entrez un mot : toto
toto toto
$

Exercice 2 :
Ecrire un programme shell untrois qui demande à l'utilisateur de saisir une suite de mots constituée d'au moins trois mots et qui affiche sur la même ligne le premier et le troisième mot saisis.

 
Sélectionnez
$ untrois
Entrez une suite de mots : un petit coucou de Rodez
un coucou
$

II-1-3. Variable en « lecture seule »

Pour définir une variable dont la valeur ne doit pas être modifiée (appelée constante dans d’autres langages de programmation), on utilise la syntaxe :

 
Sélectionnez
           declare –r nom=valeur [ nom=valeur ... ]
 
Sélectionnez
$ declare -r mess=bonjour
$

On dit que la variable mess possède l’attribut r. Une tentative de modification de la valeur d’une constante provoque une erreur.

 
Sélectionnez
$ mess=salut
-bash: mess: readonly variable
$

Pour connaître la liste des constantes définies : declare –r

 
Sélectionnez
$ declare -r
declare        -ar     BASH_VERSINFO='([0]="3"          [1]="1"      [2]="17"       [3]="1"
[4]="release" [5]="i486-pc-linux-gnu")'
declare -ir EUID="1002"
declare -ir PPID="25165"
declare -r SHELLOPTS="braceexpand:emacs:hashall:histexpand:history:
interactive-comments:monitor"
declare -ir UID="1002"
declare -r mess="bonjour"
$

Plusieurs constantes sont prédéfinies : le tableau BASH_VERSINFO (attribut a), les entiers EUID, PPID et UID (attribut i) et la chaîne SHELLOPTS.

II-2. Paramètres de position et paramètres spéciaux

II-2-1. Paramètres de position

Un paramètre de position est référencé par un ou plusieurs chiffres : 8 , 0 , 23 L’assignation de valeurs à des paramètres de position s’effectue :

  • soit à l’aide de la commande interne set
  • soit lors de l’appel d’un fichier shell ou d’une fonction shell.

on ne peut utiliser ni le symbole =, ni la commande interne read pour affecter directement une valeur à un paramètre de position.

 
Sélectionnez
$ 23=bonjour
-bash: 23=bonjour: command not found
$ read 4
aa
-bash: read: `4': not a valid identifier
$

Commande interne set : La commande interne set affecte une valeur à un ou plusieurs paramètres de position en numérotant ses arguments suivant leur position. La numérotation commence à 1.

 
Sélectionnez
Syntaxe :       set arg1 ...
 
Sélectionnez
$ set alpha beta gamma => alpha est la valeur du paramètre de position 1, beta la
                       => valeur du deuxième paramètre de position et gamma
                       => la valeur du paramètre de position 3
$

Pour obtenir la valeur d’un paramètre de position, il suffit de placer le caractère $ devant son numéro ; ainsi, $1 permet d’obtenir la valeur du premier paramètre de position, $2 la valeur du deuxième et ainsi de suite.

 
Sélectionnez
$ set ab be ga         => numérotation des mots ab, be et ga
$ echo $3 $2
ga be
$ echo $4
$

Tous les paramètres de position sont réinitialisés dès que la commande interne set est utilisée avec au moins un argument.

 
Sélectionnez
$ set coucou
$ echo $1
coucou
$ echo $2
           => les valeurs be et ga précédentes ont disparues
$

La commande set -- rend indéfinie la valeur des paramètres de position préalablement initialisés.

 
Sélectionnez
$ set alpha beta
$ echo $1
alpha
$
$ set --
$ echo $1
               => les valeurs alpha et beta sont perdues
$

Remarques :

  • Utilisée sans argument, set a un comportement différent : elle affiche la (longue) liste des noms et valeurs des variables définies.
 
Sélectionnez
$ set
BASH=/bin/bash
...
$
  • Si la valeur du premier argument de set commence par un caractère - ou +, une erreur se produit. En effet, les options de cette commande interne commencent par un de ces deux caractères. Pour éviter que ce type d’erreur ne se produise, on utilise la syntaxe : set -- arg ...
 
Sélectionnez
$ a=+qui
$ set $a
-bash: set: +q: invalid option
set: usage: set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
$ set -- $a
$ echo $1
+qui
$

II-2-2. Paramètres spéciaux

Un paramètre spécial est référencé par un caractère spécial. L’affectation d’une valeur à un paramètre spécial est effectuée par le shell. Pour obtenir la valeur d’un paramètre spécial, il suffit de placer le caractère $ devant le caractère spécial qui le représente.

Un paramètre spécial très utilisé est le paramètre # (à ne pas confondre avec le début d’un commentaire). Celui-ci contient le nombre de paramètres de position ayant une valeur.

 
Sélectionnez
$ set a b c

$ echo $#        => affichage de la valeur du paramètre spécial #
3                => il y a 3 paramètres de position ayant une valeur
$

Exercice 3 :
Ecrire un programme shell nbmots qui demande à l'utilisateur de saisir une suite quelconque de mots puis affiche le nombre de mots saisis.

 
Sélectionnez
$ nbmots
Entrez une suite de mots : un deux trois quatre cinq
5       => 5 mots ont été saisis
$

II-2-3. Commande interne shift

La commande interne shift décale la numérotation des paramètres de position ayant une valeur.

 
Sélectionnez
Syntaxe :      shift [ n ]

Elle renomme le n+1 ième paramètre de position en paramètre de position 1, le n+2 ième paramètre de position en paramètre de position 2, etc. : (n+1) => 1 , (n+2) => 2 , etc. Une fois le décalage effectué, le paramètre spécial # est mis à jour.

 
Sélectionnez
$ set a b c d e      =>     12345 
$ echo $1 $2 $#
ab5
$ shift 2    =>       abcde                  les mots a et b sont devenus inaccessibles
             =>         123
$ echo $1 $3
ce
$ echo $#
3
$

La commande interne shift sans argument est équivalente à shift 1.

shift ne modifie pas la valeur du paramètre de position 0 qui possède une signification particulière.

II-2-4. Paramètres de position et fichiers shell

Dans un fichier shell, les paramètres de position sont utilisés pour accéder aux valeurs des arguments qui ont été passés lors de son appel : cela signifie qu’au sein du fichier shell, les occurrences de $1 sont remplacées par la valeur du premier argument, celles de $2 par la valeur du deuxième argument, etc. Le paramètre spécial $# contient le nombre d’arguments passés lors de l’appel.

Le paramètre de position 0 contient le nom complet du programme shell qui s’exécute.

Soit le programme shell copie :

copie
Sélectionnez
#!/bin/bash
#        @(#)      copie
echo "Nom du programme : $0"
echo "Nb d'arguments : $#"
echo "Source : $1"
echo "Destination : $2"
cp $1 $2

Pour exécuter ce fichier shell :

 
Sélectionnez
$ chmod u+x copie
$ copie /etc/passwd X
Nom du programme : ./copie
Nb d'arguments : 2
Source : /etc/passwd
Destination : X
$

Dans le fichier copie, chaque occurrence de $1 a été remplacée par la chaîne de caractères /etc/passwd, celles de $2 par X.

Exercice 4 :
Ecrire un programme shell cp2fois prenant trois arguments : le premier désigne le nom du fichier dont on veut copier le contenu dans deux fichiers dont les noms sont passés comme deuxième et troisième arguments. Aucun cas d'erreur ne doit être considéré.

Lorsque la commande interne set est utilisée à l’intérieur d’un programme shell, la syntaxe $1 possède deux significations différentes : $1 comme premier argument du programme shell, et $1 comme premier paramètre de position initialisé par set au sein du fichier shell.

programme shell ecrase_arg
Sélectionnez
# !/bin/bash
echo '$1' est $1         => la chaîne $1 est remplacée par le premier argument
set hello                => set écrase la valeur précédente de $1
echo '$1' est $1
 
Sélectionnez
$ ecrase_arg bonjour coucou salut
$1 est bonjour
$1 est hello
$

II-2-5. Paramètres spéciaux * et @

Les paramètres spéciaux @ et * contiennent tous deux la liste des valeurs des paramètres de position initialisés.

 
Sélectionnez
$ set un deux trois quatre
$ echo $*
un deux trois quatre
$ echo $@
un deux trois quatre
$

Ces deux paramètres spéciaux ont des valeurs distinctes lorsque leur référence est placée entre des guillemets ("$*" et "$@") :

 
Sélectionnez
         "$*" est remplacée par        "$1 $2 ... "
         "$@" est remplacée par        "$1" "$2" ...
 
Sélectionnez
$ set un deux trois                   => trois paramètres de position sont initialisés
$ set "$*"                            => est équivalent à : set “un deux trois”
$ echo $#
1
$ echo $1
un deux trois
$

L’intérêt de la syntaxe "$*" est de pouvoir considérer l’ensemble des paramètres de position initialisés comme une unique chaîne de caractères. La syntaxe "$@" produit autant de chaînes que de paramètres de positions initialisés.

 
Sélectionnez
$ set un deux trois            => trois paramètres de position initialisés
$ set "$@"                     => est équivalent à : set “un” “deux” “trois”
$ echo $#
3
$ echo $1
un
$

Variable prédéfinie IFS et paramètre spécial "$*" :

La variable prédéfinie du shell IFS contient les caractères séparateurs de mots dans une commande. Par défaut, ce sont les caractères espace, tabulation et interligne. L’initialisation de IFS est effectuée par bash.

Le shell utilise le premier caractère mémorisé dans IFS (par défaut, le caractère espace) pour séparer les différents paramètres de position lorsque la syntaxe "$*" est utilisée. En modifiant la valeur de IFS, l’utilisateur peut changer ce caractère séparateur.

 
Sélectionnez
$ IFS=:                      => le caractère deux-points est maintenant le premier caractère de IFS
$ set un deux trois quatre
$ echo $*
un deux trois quatre
$ echo "$@"
un deux trois quatre
$ echo "$*"
un:deux:trois:quatre         => seule la forme "$*" provoque un changement
$

II-3. Suppression des ambiguïtés

Pour éviter les ambiguïtés dans l’interprétation des références de paramètres, on utilise la syntaxe ${paramètre}.

 
Sélectionnez
$ x=bon
$ x1=jour
$ echo $x1                  => valeur de la variable x1
jour
$ echo ${x}1                             => pour concaténer la valeur de la variable x à la chaîne ′′1′′
bon1
$
 
Sélectionnez
$ set un deux trois quatre cinq six sept huit neuf dix onze douze
$ echo $11
un1
$ echo ${11}                             => pour obtenir la valeur du onzième paramètre de position
onze
$

II-4. Paramètres non définis

Trois cas peuvent se présenter lorsque le shell doit évaluer un paramètre :

  • le paramètre n’est pas défini,
  • le paramètre est défini mais ne possède aucune valeur (valeur vide),
  • le paramètre possède une valeur non vide.

Lorsque l’option nounset de la commande interne set est positionnée à l’état on (commande set -o nounset), bash affiche un message d’erreur quand il doit évaluer un paramètre non défini.

 
Sélectionnez
$ set -o nounset                         => option nounset à l’état on
$ echo $c                                => variable utilisateur c non définie,
-bash: c: unbound variable               => message d’erreur !
$ echo $1
-bash: $1: unbound variable
$ d=                                     => d : variable définie mais vide
$ echo $d
                                         => valeur null, pas d’erreur
$

La présence de paramètres non définis ou définis mais vides dans une commande peut mener son exécution à l’échec. Afin de traiter ce type de problème, bash fournit plusieurs mécanismes supplémentaires de substitution de paramètres. L’un d’eux consiste à associer au paramètre une valeur ponctuelle lorsqu’il est non défini ou bien défini vide. La syntaxe à utiliser est la suivante : ${paramètre:-chaîne}

 
Sélectionnez
$ set -o nounset
$ ut1=root                        => ut1 définie et non vide
$ ut2=                            => ut2 définie et vide
$ echo $ut1
root
$ echo $ut2
$ echo $1
-bash: $1: unbound variable       => paramètre de position 1 non défini
$

Avec la syntaxe mentionnée ci-dessus, il est possible d’associer temporairement une valeur par défaut aux trois paramètres.

 
Sélectionnez
$ echo ${ut1:-sanchis}
root                             => ut1 étant définie non vide, elle conserve sa valeur
$ echo ${ut2:-sanchis}           => ut2 est définie et vide, la valeur de remplacement est
sanchis                          =>      utilisée
$ echo ${1:-sanchis}
sanchis                          => le premier paramètre de position est non défini
$

Cette association ne dure que le temps d’exécution de la commande.

 
Sélectionnez
$ echo $1
-bash: $1: unbound variable       => le paramètre est redevenu indéfini
$

La commande set +o nounset positionne l’option nounset à l’état off : le shell traite les paramètres non définis comme des paramètres vides.

 
Sélectionnez
$ set +o nounset              => option nounset à l’état off
$ echo $e                     => variable e non définie,
                              => aucune erreur signalée
$ echo $2
                              => aucune erreur signalée
$ f=                          => f : variable définie vide
$ echo $f
$

II-5. Suppression de variables

Pour rendre indéfinies une ou plusieurs variables, on utilise la commande interne unset.

 
Sélectionnez
Syntaxe :     unset var [ var1 . . . ]
 
Sélectionnez
$ a=coucou             => la variable a est définie
$ echo $a
coucou
$ unset a              => la variable a est supprimée
$ set -o nounset       => pour afficher le message d’erreur
$ echo $a
-bash: a: unbound variable
$

Une variable en « lecture seule » ne peut être supprimée par unset.

 
Sélectionnez
$ declare -r a=coucou             => définition de la constante a
$ echo $a
coucou
$ unset a
-bash: unset: a: cannot unset: readonly variable
$

précédentsommairesuivant

Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.