Les variables réservées du shell

Dans un script, il est possible de récupérer en lecture un certain nombre de variables réservées.
Ces variables sont initialisées par le shell et contiennent des informations diverses et variées.

Les paramètres positionnels

Les scripts shell sont capables de récupérer des arguments placés juste après l'appel du script.

  • $# indique le nombre d'arguments passés au script
  • $0 indique le nom du script
  • $1, $2, $3 ... $9 contient la valeur de l'argument 1, 2, 3 ... 9

En KSH et en BASH, il est possible d'aller au delà de 9 arguments en utilisant les variables spéciales ${10}, ${11} etc...
Les accolades sont obligatoires à partir du moment où le nom de la variable contient plus d'un chiffre.

  • $* et $@ contient la liste de tous les arguments

Exemple :

$ nano monSecondScript.sh
#! /bin/bash
echo "Il y a $# arguments passés au script"
echo "Le script se nomme $0"
echo "La valeur du premier argument : $1"
echo "La valeur du second argument : $2"
echo "La valeur du troisième argument : $3"
echo "Les valeurs de tous les arguments : $*"
^o (enregistrer)
^x (quitter)
$ chmod u+x monSecondScript.sh
$ ./monSecondScript.sh arg1 arg2 arg3 arg4 arg5
Il y a 5 arguments passés au script
Le script se nomme ./monSecondScript.sh
La valeur du premier argument : arg1
La valeur du second argument : arg2
La valeur du troisième argument : arg3
Les valeurs de tous les arguments : arg1 arg2 arg3 arg4 arg5
$

Exemple avec 3 arguments :

$ ./monSecondScript.sh 25 + 15
Il y a 3 arguments passés au script
Le script se nomme ./monSecondScript.sh
La valeur du premier argument : 25
La valeur du second argument : +
La valeur du troisième argument : 15
Les valeurs de tous les arguments : 25 + 15
$

Tous les arguments doivent être séparés les uns des autres par un espace ou une tabulation

La commande shift

La commande shift permet de décaler la liste des arguments d'une ou plusieurs positions vers la gauche.

Cette commande est utilisée dans le cas où le premier argument n'a pas à subir le même traitement que les suivants.
Dans ce cas, le premier argument doit être sauvegardé dans une variable et l'exécution de la commande shift entraine le remplacement du premier argument par le second et ainsi de suite.

$ nl monTroisiemeScript.sh
     1  #! /bin/bash
     2  # Ce script doit recevoir en premier argument le nom d'un dossier puis des noms de fichiers pour les suivants
     3  # Affichage des variables avant l'utilisation de la commande shift
     4  echo -e "Affichage avant exécution de la commande shift\n"
     5  echo "1er argument \$1 : $1"
     6  echo "1er argument \$2 : $2"
     7  echo "1er argument \$3 : $3"
     8  echo "1er argument \$4 : $4"
     9  echo "Tous les arguments \$* : $*"
    10  echo -e "Le nombre d'argument \$# : $#\n"
    11  # On sauvegarde le premier argument dans la variable rep
    12  rep=$1
    13  # On décale tous les arguments avec la commande shift
    14  shift
    15  # Affichage des variables après l'exécution de la commande shift
    16  echo -e "Affichage après exécution de la commande shift\n"
    17  echo "1er argument \$1 : $1"
    18  echo "1er argument \$2 : $2"
    19  echo "1er argument \$3 : $3"
    20  echo "1er argument \$4 : $4"
    21  echo "Tous les arguments \$* : $*"
    22  echo -e "Le nombre d'argument \$# : $#\n"
    23  # Création du répertoire
    24  mkdir $rep
    25  # On se positionne dans le nouveau répertoire
    26  cd $rep
    27  # Création des fichiers dans le nouveau répertoire
    28  for fichier in $*
    29  do
    30          touch $fichier
    31  done
$ chmod u+x monTroisiemeScript

Exécution du script :

$ ./monTroisiemeScript.sh test fic1 fic2 fic3 fic4 fic5 fic6
Affichage avant exécution de la commande shift
1er argument $1 : test
1er argument $2 : fic1
1er argument $3 : fic2
1er argument $4 : fic3
Tous les arguments $* : test fic1 fic2 fic3 fic4 fic5 fic6
Le nombre d'argument $# : 7
Affichage après exécution de la commande shift
1er argument $1 : fic1
1er argument $2 : fic2
1er argument $3 : fic3
1er argument $4 : fic4
Tous les arguments $* : fic1 fic2 fic3 fic4 fic5 fic6
Le nombre d'argument $# : 6
ls -l ./test/
total 0
-rw-r--r-- 1 toto toto 0 2011-10-25 09:01 fic1
-rw-r--r-- 1 toto toto 0 2011-10-25 09:01 fic2
-rw-r--r-- 1 toto toto 0 2011-10-25 09:01 fic3
-rw-r--r-- 1 toto toto 0 2011-10-25 09:01 fic4
-rw-r--r-- 1 toto toto 0 2011-10-25 09:01 fic5
-rw-r--r-- 1 toto toto 0 2011-10-25 09:01 fic6
$

Code de retour d'une commande

Toutes les commandes Linux retournent un code d'erreur compris entre 0 et 255.
La valeur 0 représente la valeur vrai (succès de la commande).
Les valeurs supérieur à 0 représente la valeur faux (échec de la commande).
Le code erreur de la dernière commande utilisée est contenu dans la variable $?

$ ls f*
f1chier               fichier159159.log  fichier159.log  fichier161.log  fichier1.abc  fichier1.c   fset
fichier159159159.log  fichier159160.log  fichier160.log  fichier1.a      fichier1.b    fichier.log
$ echo $?
0
$ ls 2*
ls: impossible d'accéder à 2*: Aucun fichier ou dossier de ce type
$ echo $?
2

Dans un script shell, le test du code de retour d'une commande permet d'effectuer différentes actions.

Un script shell étant lui-même une commande, il est possible de lui faire retourner un code d'erreur avec la commande exit.

Par exemple, il est possible d'indiquer dans un script exit 1 afin d'indiquer une erreur rencontrée et/ou exit 0 afin d'indiquer que tout c'est bien déroulé.

Dans l'exemple suivant, le script test s'il reçoit bien au minimum 2 arguments et renvoi le code erreur 1 si c'est faux.

$ nl ./script.sh
1  #! /bin/bash
2  # Le script doit recevoir au minimum 2 arguments
3  if [ $# -lt 2 ]
4  then
5          # Si le nombre d'arguments est inférieur à 2
6          # on retourne le code erreur 1
7          echo "Nombre arguments incorrect"
8          exit 1
9  else
10          # Si le nombre d'arguments est supérieur ou égal à 2
11          # on retourne le code erreur 0
12          echo "Nombre arguments correct"
13          exit 0
14  fi
$

Exécution du script :

$ ./script.sh
Nombre arguments incorrect
$ echo $?
1
$ ./script.sh test
Nombre arguments incorrect
$ echo $?
1
$ ./script.sh test test2
Nombre arguments correct
$ echo $?
0
$

Autres variables spéciales

La variable $$ représente le PID du shell qui interprète le script.
La valeur de cette variable est la même pendant toute la durée d'exécution du script et différente à chaque utilisation du script.

Exemple :

Dans ce script, la variable $$ est utilisée pour générer le nom d'un dossier différent à chaque exécution du script.

$ nl monQuatriemeScript.sh
     1  #! /bin/bash
     2  dossierTemp=dossier_$$
     3  echo "Création du dossier \"$dossierTemp\""
     4  mkdir $dossierTemp
     5  cd $dossierTemp
     6  for (( i=0 ; i<10 ; i++)) do
     7          touch fichier_$i
     8  done
     9  exit 0
$

$ ./monQuatriemeScript.sh
Création du dossier "dossier_26563"
$ ./monQuatriemeScript.sh
Création du dossier "dossier_26581"
$

La variable $! représente le PID d'une commande exécutée en arrière plan.

exemple :

$ nl monCinquiemeScript.sh
     1  #! /bin/bash
     2  echo "Le script est exécuté sous le PID $$"
     3  find /etc -name $1 1> resultat 2> /dev/null &
     4  echo "La commande FIND est en cours d'exécution sous le PID $!"
     5  ps
     6  exit 0
$

$ ./monCinquiemeScript.sh hosts.allow
Le script est exécuté sous le PID 29999
La commande FIND est en cours d'exécution sous le PID 30000
  PID TTY          TIME CMD
19703 pts/0    00:00:00 bash
29999 pts/0    00:00:00 monCinquiemeScr
30000 pts/0    00:00:00 find
30001 pts/0    00:00:00 ps
$