Je déterre ce thread dans l'espoir que ça serve à quelqu'un.
Ça ne fonctionne pas car le compteur est incrémenté dans un processus fils par rapport à celui où il est initialisé et celui où on veut récupérer sa valeur après la boucle.
Les structures de ce type :
1. cpt=10
2. (echo 1; echo 2; echo 3) | while read var; do
3. cpt=$((cpt+1)) # une notation pas trop mal pour faire une incrémentation en bash
4. echo "$var: cpt=$cpt" # affiche 11, 12, 13
5. done
6. echo $cpt # affiche 10, pas 13
|
sont pratiques avec le "while read" (pas besoin de faire de tableau ou de stocker dans un fichier temporaire) mais il n'est pas possible de récupérer une valeur calculée à l'intérieur du while.
C'est à cause du fait que à la ligne 3 on est dans un processus (appelons-le B) différent de celui de la ligne 1 et ligne 6 (processus A). En effet, le pipe de la ligne 2 a pour effet que le processus A fork en donnant un processus B (la sortie standard de A est redirigée vers l'entrée standard de B).
Lorsqu'un processus est forké, son fils B connaît le même environnement que le père A (notamment les variables), mais c'est un environnement distinct (car il est dupliqué au moment du fork).
Le père A ne connaît donc pas la valeur de la variable $cpt du fils B, et $cpt vaut toujours la même chose qu'avant le "| while", soit 10 dans l'exemple. L'export ne résoud rien car ça export les variables du père vers le fils, pas dans l'autre sens.
Donc pour avoir la valeur 13 dans $cpt à la fin, il faut éviter le pipe "|".
Par exemple :
1. while read var; do
2. cpt=$((cpt+1));
3. echo "$var. cpt=$cpt"; done << EOF
4. done << EOF
5. $(echo 1; echo 2; echo 3)
6. EOF
|
Entrée, sortie, redirection : http://www.tuteurs.ens.fr/unix/shell/entreesortie.html