Les structures de contrôle



--Téléchargez Les structures de contrôle en PDF --


Rappel sur les codes de retour de programmes UNIX

Le noyau UNIX a prévu qu’un programme pouvait, après son exécution, transmettre une valeur à celui qui l’a lancé. En dernière instruction, un programme exécute exit(n), où n est la valeur à transmettre, et l’appelant exécute wait(&status), où status est une variable dans laquelle le noyau UNIX met la valeur transmise.

Ces valeurs ainsi transmises servent de code de retour des programmes: elles servent à donner une indication sur la façon dont s’est déroulée l’exécution du programme. Par convention, la valeur 0 signifie que l’exécution du programme s’est déroulée sans erreur. Une valeur différente de zéro signifie qu’il y a eu une erreur, la valeur étant un code choisi par le programmeur de l’application.

La gestion des codes de retour par le shell

Code de retour d’un programme

Quand le shell lance l’exécution d’un programme en avant plan, il attend la fin de l’exécution par un wait(&status). Il est ainsi prévenu du code de retour du programme. Le shell affecte ce code de retour à la variable ?, que l’on peut manipuler comme n’importe quelle variable.

Faisons un essai avec la commande grep, qui rend une indication d’erreur quand elle ne trouve pas la chaîne qu’on lui demande de rechercher :

Quand le shell lance l’exécution d’un programme en arrière-plan, il n’attend pas la fin de l’exécution et ne peut donc pas  connaître le code de retour. Dans ce cas, la valeur de la variable ? reflète la manière dont le lancement en programme d’arrière-plan s’est passé:

  • Si le lancement a pu être réalisé (les fichiers de redirection des entrées-sorties existaient bien, etc…), la variable ? vaut 0.
  • Si le lancement n’a pu être réalisé, la variable ? vaut 1.

Code de retour d’un pipe-line

Un pipe-line est un ensemble de commandes connectées par des pipes. Par exemple : >  grep -i bob /etc/passwd | wc -l

Le code de retour d’un pipe-line est le code de retour de la dernière commande du pipe-line.

Code de retour d’une séquence de commandes

Le code de retour d’une séquence de commandes est le code de retour de la dernière commande de la séquence.

La structure &&

Deux pipe-lines peuvent être connectés par la structure &&. Cela signifie :

Si le premier pipe-line rend un code de retour de 0, le second est exécuté, sinon il n’est pas exécuté.

La structure ||

Deux pipe-lines peuvent être connectés par la structure ||. Cela signifie : Si le premier pipe-line rend un code de retour différent de 0, le second est exécuté, sinon il n’est pas exécuté.

Cette structure est bien adaptée à l’émission conditionnelle de messages d’erreurs.

Exemple :

grep $USER /etc/passwd || echo "$USER" "n'existe pas"

Remplace avantageusement :

Le code de retour d’une structure || est le code de retour du dernier pipe-line exécuté.

La structure for

Dans liste-de-pipe-lines les commandes peuvent être séparées par des points virgules ou par des retour chariot.

La partie in (liste-de-mots ) est optionnelle. Si elle est omise, le shell la remplace par « $@ » (=ensemble des paramètres sur la ligne de commandes, chacun étant protégé par ‘’ ‘’).

Ecriture d’un for sur une seule ligne :

La structure for itère l’exécution de liste-de-pipe-lines. A chaque pas de l’itération, la variable nom prend comme valeur le mot suivant de liste-de-mots.

Exemples :

A l’aide de la commande seq (qui affiche une séquence de nombre)

La structure if

Il y a plusieurs formes possibles : avec ou sans partie else, partie else combinée avec un if pour faire un elif (else if).

ou:

ou:

Ecriture d’un if sur une seule ligne:

La conditions après le if est exécutée, si elle rend un code de retour nul, la liste-de-pipe-lines de la partie then est exécutée, sinon, la liste-de-pipe-lines de la partie else est exécutée.

Dans la pratique, la liste-de-pipe-lines après le if est généralement réduite à une seule commande.

Exemple :

La structure case

Dans les listes-de-modèles les modèles sont séparés par le caractère |

Les modèles sont les mêmes que ceux qui servent de modèles de noms de fichiers. Les métacaractères sont * ? [ ] avec la même sémantique. Un mot est dit conforme à une liste-de-modèles sil est conforme à un des modèles de la liste. Le caractère | a donc le sens d’un « ou ».

Le mot est comparé successivement à chaque liste-de-modèles. A la première liste-de-modèles pour laquelle le mot correspond, on exécute la liste-de-pipe-lines correspondante.

Exemples :

La structure while

La structure while itère :

  • exécution de la liste-de-pipe-lines du while
  • si celle ci rend un code de retour nul il y a exécution de la liste-de-pipe-lines du do,
  • sinon la boucle se termine.

De la même manière que pour la structure if, la liste-de-pipe-lines de la partie while est généralement réduite à une seule commande.

Exemples :

L’exemple ci-dessous réalise une boucle de 10 itérations :

La structure until

La structure until itère l’exécution de la liste-de-pipe-lines du until ; si celle-ci rend un code de retour nul, il y a exécution de la liste-de-pipe-lines du do, sinon la boucle se termine.

De la même manière que pour la structure if, la liste-de-pipe-lines de la partie until est généralement réduite à une seule commande.

Break et continue

Il est possible de sortir d’une boucle for, while ou until à l’aide de la commande interne break. (Pour une bonne logique et compréhension de votre programmation ceci est fortement déconseillé). Il est possible d’indiquer un paramètre numérique permettant de sortir de plusieurs boucles à la fois.

Exemple :

Redirection des entrées-sorties

Il est possible de rediriger les entrées-sorties d’une structure conditionnelle (if ou case) ou de boucle (for, while, until).

Exemple :

Chaque commande peut avoir ses entrées-sorties redirigées indépendamment :

Pipe

Il est possible de piper les mêmes structures soit en entrée soit en sortie.

Exemple :

Exécution en arrière-plan

Il est possible d’exécuter les structures de contrôle en arrière-plan.

Attention, quand on redirige ou que l’on pipe les entrées-sorties ou que l’on met dans l’arrière-plan une telle structure, celle-ci est exécutée dans un sous-shell. Attention donc si on utilise des variables :

A la fin, la variable nbligne vaut toujours 0 ! Il y a eu incrémentation de la variable nbligne du sous-shell créé pour exécuter le while puis disparition de cette variable lors de la fin du

while qui a entraîné la mort du sous-shell.