Vous êtes ici :
Accueil Cours Administration Système La programmation Système avec Shell La substitution de paramètres

La programmation Système avec Shell : La 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
Exemple :  a  ,  PATH
–  les paramètres de position, identifiés par un numéro
Exemple :  0  ,  1  ,  12
–  les paramètres spéciaux, identifiés par un caractère spécial
Exemple :  #  ,  ?  ,  $
 
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.
 

Exemple :

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

 

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 : HOSTNAME, 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.
 

  1. Affectation directe

 

 
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.
 
Exemple :

$ 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 =.
 
Exemple :

  $ b   =coucou
-bash: b: command not found
$ 
Le shell interprète b comme une commande à exécuter ; ne la trouvant pas, il signale une erreur.
-  un ou plusieurs caractères espace entre le symbole = et la valeur de la variable.  
 
Exemple : 

$ y=   coucou
-bash: coucou: command not found    
$        
 
La chaîne "coucou" est interprétée comme la commande à exécuter.
 Lorsque le shell rencontre la chaîne $x, il la remplace textuellement par la valeur de la variable x, c'est-à-dire.  "coucou" ; la commande exécutée par bash est : echo x est "coucou"
 
Exemple :

 $ 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.
 
Exemple : 

 $ x=$x$y   =>  x : contenant,  $x : contenu
$ echo $x
coucoubonjour
$  
 
 

  1.   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.
 
Syntaxe :  read  [  var1  ... ]
 
Exemple :

$ 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 .
 
Exemple : 

$ 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 : 

read –p chaîne_d_appel [ var … ]
 
Exemple :

 $ read -p "Entrez votre prenom : " prenom
Entrez votre prenom : Tony
$
$ echo $prenom
Tony
$
 
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.
 

Exemple :

 $ 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'est-à-dire. initialisées à la valeur null).
 
Exemple :

$ read a b
Un
$  
$ echo $a

Un
$  
$ echo $b
     =>  valeur null
$  
 

  • 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 :  
declare  –r  nom=valeur [ nom=valeur … ]
 
Exemple : 

$ 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.
 
Exemple : 

$ mess=salut
-bash: mess: readonly variable
$
 
Pour connaître la liste des constantes définies :  declare  –r  
 

Exemple : 

$ 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.

 

Paramètres de position et paramètres spéciaux

 

  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.

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

  $ 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.
 
Syntaxe :  set  arg1  ..


Exemple : 

$ 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.
 
Exemple : 

$ 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.
 
Exemple :

$ 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.
Exemple :

$ 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.
 
Exemple :

$ 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 ...
 
Exemple :

 $ a=+qui
$ set $a

-bash: set: +q: invalid option
set: usage: set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
$ set -- $a
$  
$ echo $1

+qui
$  
 

  1. 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.
 
Exemple: 

$ 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       
$

 

  1. Commande interne shift

 

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

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.
 
Exemple : 

$ set a b c d e
 =>      1  2  3  4  5  
$ echo $1 $2 $#
a b 5
$
$ shift 2
=>   a b c d e    les mots a et b sont devenus inaccessibles
=>         1 2 3  
$ echo $1 $3
c e
$ echo $#
3
$
 
La commande interne shift sans argument est équivalente à shift 1.
 
Remarque :   shift ne modifie pas la valeur du paramètre de position  0 qui possède une signification particulière.

 

  1. 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 exécuté.
 
Soit le programme shell copie :

#!/bin/bash 

echo "Nom du programme : $0" 
echo "Nb d'arguments : $#" 
echo "Source : $1" 
echo "Destination : $2" 
cp $1 $2 

 

Pour exécuter ce fichier shell :
 
$ chmod u+x  copie
$
$ copie /etc/passwd  X

affiche à l'écran

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.
 
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.
 

Exemple :  programme shell ecrase_arg

 

# !/bin/bash 
 
echo '$1' est $1 # la chaine $1 est remplacee par le premier argument 
set hello #  set ecrase la valeur precedente de $1 
echo '$1' est $1 

 

Exemple d'execution :

$ ecrase_arg bonjour coucou salut
affiche

$1 est bonjour
$1 est hello
$

 

  1. 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.
 
Exemple : 

$ 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 "$@") :
 
"$*"   est remplacée par   "$1 $2 ... "
"$@"  est remplacée par  "$1"  "$2" ...   
 

 
Exemple : 

$ 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.
 

Exemple :

$ 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.
 
Exemple : 

$ 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  
$

 

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}.
 
Exemple : 

$ 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


$ 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
$ 

 

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.
 
Exemple : 

$ 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}
 
Exemple : 

$ 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.
 

Exemple :

$ echo ${ut1:-foo}
root    => ut1 étant définie non vide, elle conserve sa valeur
$
$ echo ${ut2:-bar}  => ut2 est définie et vide, la valeur de remplacement est
bar    =>       utilisée
$
$ echo ${1:-beer}
bar    => le premier paramètre de position est non défini
$
 
Cette association ne dure que le temps d’exécution de la commande.  
 

Exemple :

$ 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.
 

 
Exemple : 

$ 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
 
$

 

Suppression de variables

 

Pour rendre indéfinies une ou plusieurs variables, on utilise la commande interne unset.
 
Syntaxe :  unset  var [ var1 . . . ]
 
Exemple :

$ 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.
 
Exemple : 

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

 

 




Vous êtes ici :
Accueil Cours Administration Système La programmation Système avec Shell La substitution de paramètres