variables visibles seulement à l'intérieur d'un bloc de code ou d'une fonction (voir aussi variables locales dans fonctions)
variables qui affectent le comportement du shell et de l'interface utilisateur
Dans un contexte plus général, chaque processus a un « environnement », c'est-à-dire un groupe de variables contenant des informations auxquelles pourrait faire référence le processus. En ce sens, le shell se comporte comme n'importe quel processus.
Chaque fois qu'un shell démarre, il crée les variables shell correspondantes à ses propres variables d'environnement. Mettre à jour ou ajouter de nouvelles variables d'environnement force le shell à mettre à jour son environnement, et tous les processus fils (les commandes qu'il exécute) héritent de cet environnement.
L'espace alloué à l'environnement est limité. Créer trop de variables d'environnement ou une variable d'environnement qui utilise un espace excessif peut causer des problèmes.
bash$ eval "`seq 10000 | sed -e 's/.*/export var&=ZZZZZZZZZZZZZZ/'`" bash$ du bash: /usr/bin/du: Argument list too long
(Merci à Stéphane Chazelas pour la clarification et pour avoir fourni l'exemple ci-dessus.)
Si un script déclare des variables d'environnement, il faut qu'elles soient « exportées », c'est-à-dire, rapportées à l'environnement local du script. C'est la fonction de la commande export .
Un script peut exporter des variables seulement aux processus fils, c'est-à-dire seulement aux commandes ou processus que ce script particulier initie. Un script invoqué depuis la ligne de commande ne peut pas ré-exporter des variables à destination de l'environnement de la ligne de commande dont il est issu. Des processus fils ne peuvent pas réexporter de variables aux processus parents qui les ont fait naître.
Définition : un processus enfant est un sous-processus lancé par un autre processus appelé parent.
---
Ce sont les arguments passés aux scripts depuis la ligne de commande - $0, $1, $2, $3...
$0 est le nom du script lui-même, $1 est le premier argument, $2 le second, $3 le troisième, et ainsi de suite. [23] Après $9, les arguments doivent être entourés d'accolades, par exemple ${10}, ${11}, ${12}.
Les variables spéciales $* et $@ représentent tous les paramètres positionnels.
Exemple 4.5. Paramètres positionnels
#!/bin/bash # Appelez ce script avec au moins 10 paramètres, par exemple # ./nom_script 1 2 3 4 5 6 7 8 9 10 MINPARAMS=10 echo echo "Le nom de ce script est \"$0\"." # Ajoutez ./ pour le répertoire courant. echo "Le nom de ce script est \"`basename $0`\"." # Supprime le chemin du script (voir 'basename') echo if [ -n "$1" ] # La variable testée est entre guillemets. then echo "Le paramètre #1 est $1" # Nous avons besoin des guillemets pour échapper # fi if [ -n "$2" ] then echo "Le paramètre #2 est $2" fi if [ -n "$3" ] then echo "Le paramètre #3 est $3" fi # ... if [ -n "${10}" ] # Les paramètres supérieures à $9 doivent être compris entre #+ accolades. then echo "Le paramètre #10 est ${10}" fi echo "-----------------------------------" echo "Tous les paramètres de la ligne de commande sont: "$*"" if [ $# -lt "$MINPARAMS" ] then echo echo "Ce script a besoin d'au moins $MINPARAMS arguments en ligne de commande!" fi echo exit 0
La notation avec accolades pour les paramètres positionnels permet de référencer plutôt simplement le dernier argument passé à un script sur la ligne de commande. Ceci requiert également le référencement indirect.
args=$# # Nombre d'arguments passés. dernarg=${!args} # Ou : dernarg=${!#} # (Merci à Chris Monson) # Notez que dernarg=${!$#} ne fonctionne pas.
Certains scripts peuvent effectuer différentes opérations suivant le nom sous lequel ils sont invoqués. Pour que cela fonctionne, le script a besoin de tester $0, le nom sous lequel il a été invoqué. Il doit aussi y avoir des liens symboliques vers tous les différents noms du script. Voir l'Exemple 15.2, « Hello or Good-bye ».
Si un script attend un paramètre en ligne de commande mais qu'il est invoqué sans, cela peut causer une affectation à valeur nulle, généralement un résultat non désiré. Une façon d'empêcher cela est d'ajouter un caractère supplémentaire des deux côtés de l'instruction d'affectation utilisant le paramètre positionnel attendu.
variable1_=$1_ # Plutôt que variable1_=$1 # Cela préviendra l'erreur, même si le paramètre positionnel est absent. argument_critique01=$variable1_ # Le caractère supplémentaire peut être retiré plus tard comme ceci. variable1=${variable1_/_/} # Il n'y aura d'effets de bord que si $variable1_ commence par un tiret bas. # Ceci utilise un des patrons de substitution de paramètres discutés plus tard # (laisser vide le motif de remplacement aboutit à une destruction). # Une façon plus directe de résoudre ce problème est de simplement tester #+ si le paramètre postionnel attendu a bien été passé. if [ -z $1 ] then exit $E_PARAM_POS_MANQUANT fi # Néanmoins, comme l'indique Fabian Kreutz, #+ la méthode ci-dessus pourrait avoir des effets de bord. # Une meilleure méthode est la substitution de paramètres : # ${1:-$DefaultVal} # Voir la section « Substitution de paramètres » #+ dans le chapitre « Les variables revisitées ».
---
Exemple 4.6. wh, recherche d'un nom de domaine avec whois
#!/bin/bash # ex18.sh # Fait une recherche 'whois nom-domaine' sur l'un des trois serveurs: # ripe.net, cw.net, radb.net # Placez ce script -- renommé 'wh' -- dans /usr/local/bin # Requiert les liens symboliques : # ln -s /usr/local/bin/wh /usr/local/bin/wh-ripe # ln -s /usr/local/bin/wh /usr/local/bin/wh-cw # ln -s /usr/local/bin/wh /usr/local/bin/wh-radb E_SANSARGS=65 if [ -z "$1" ] then echo "Usage: `basename $0` [nom-domaine]" exit $E_SANSARGS fi # Vérifie le nom du script et appelle le bon serveur case `basename $0` in # Ou : case ${0##*/} in "wh" ) whois $1@whois.ripe.net;; "wh-ripe") whois $1@whois.ripe.net;; "wh-radb") whois $1@whois.radb.net;; "wh-cw" ) whois $1@whois.cw.net;; * ) echo "Usage: `basename $0` [nom-domaine]";; esac exit $?
---
La commande shift réassigne les paramètres positionnels, ce qui a le même effet que de les déplacer vers la gauche d'un rang.
$1 <--- $2, $2 <--- $3, $3 <--- $4, etc.
Le vieux $1 disparaît mais $0 (le nom du script) ne change pas. Si vous faites usage d'un grand nombre de paramètres positionnels dans un script, shift vous permet d'accèder à ceux au-delà de 10, bien que la notation {accolades} le permette également.
Exemple 4.7. Utiliser shift
#!/bin/bash # shft.sh : Utilisation de 'shift' pour voir tous les paramètres de position. # Nommez ce script quelque chose comme shft.sh, #+ et exécutez-le avec quelques paramètres. #+ Par exemple : # sh shft.sh a b c def 23 skidoo until [ -z "$1" ] # Jusqu'à ne plus avoir de paramètres... do echo -n "$1 " shift done echo # Retour chariot supplémentaire. exit 0 # Voir aussi le script echo-params.sh #+ pour une méthode n'utilisant pas shift pour passer de paramètre en paramètre.
La commande shift peut prendre un paramètre numérique indiquant le nombre de décalages.
#!/bin/bash # shift-past.sh shift 3 # Décale de 3 positions. # n=3; shift $n # a le même effet. echo "$1" exit 0 $ sh shift-past.sh 1 2 3 4 5 4 # Néanmoins, comme Eleni Fragkiadaki l'indique, #+ tenter un 'shift' après le nombre de paramètres de position #+ ($#) renvoie un code de sortie de 1, et les paramètres de #+ position ne changent pas. # Cela signifie qu'il est possible d'aboutir à une boucle sans fin... # Par exemple : # until [ -z "$1" ] # do # echo -n "$1 " # shift 20 # Si moins de 20 paramètres de position, # done #+ la boucle ne termine jamais ! # # En cas de doute, ajoutez une vérification... # shift 20 || break # ^^^^^^^^
La commande shift fonctionne d'une façon similaire à la façon de passer des paramètres à une fonction. Voir l'Exemple 33.15, « Astuce de valeur de retour ».