Forum Programmation.shell [Bash] Boucle while - export variable

Posté par .
Tags : aucun
1
14
fév.
2007
Bonjour,

J'ai une question... quand j'exécute le script suivant :

#!/bin/bash

I=-1;
cat file.txt | while read REF_LINE
do
{
let I++;
}
done
echo "I = "$I;


J=-1;
while [ $J -lt 100 ]
do
{
let J++;
}
done
echo "J = "$J;



j'obtiens l'affichage :

I = -1
J = 100



Pourquoi la variable I n'est elle pas exportée hors de la boucle?
Et surtout, comment faire pour récupérer sa valeur?

Merci d'avance de votre aide :)
  • # Fichier Vide ou condition non vérifiée ?

    Posté par . Évalué à 1.

    Ton fichier n'est-il pas vide ?

    On dirait que ton script n'entre pas dans la boucle while !
    Je dirait que cette condition -> cat file.txt | while read REF_LINE

    n'est pas vérifiée.
  • # le pipe crée un sous-processus indépendant

    Posté par . Évalué à 3.

    Lorsque tu fais "cat file | commande", en interne bash forke un sous-shell, avec tout son environnement, pour "commande" et le connecte au pipe.
    Dans ton cas, tout ce qui est fait par le "while..." est dans ce sous-shell, y compris l'incrémentation de la variable. Mais l'environnement du sous-shell n'est pas retransmis au père à la fin ! Quand tu lis cette variable plus loin dans ton script, elle a toujours sa valeur d'avant le fork. C'est une "autre" variable en somme.
    C'est visible de cette manière:

    I=1

    cat file.txt | { while read REF_LINE
    do
    let I++;
    echo $I;
    done

    echo dedans: $I
    }
    echo dehors: $I


    2
    3
    4
    dedans: 4
    dehors: 1


    La tout de suite, je ne sais pas comment regler le probleme...
    • [^] # Re: le pipe crée un sous-processus indépendant

      Posté par . Évalué à 1.

      un export $I dans la boucle pourrais peut etre aider mais qu'en est-il de la performance ?
    • [^] # Re: le pipe crée un sous-processus indépendant

      Posté par . Évalué à 1.

      -- snip --
      { while read REF_LINE
      do
      let I++;
      echo $I;
      done

      echo dedans: $I
      } < cat file.txt
      echo dehors: $I
      -- snip --

      Ceci fonctionne ici.

      J'en profite pour poser une question : pourquoi je vois souvent "cat file.txt | grep toto", plutôt que grep toto file.txt ? Quel est l'avantage ?
      • [^] # Re: le pipe crée un sous-processus indépendant

        Posté par . Évalué à 3.

        >pourquoi je vois souvent "cat file.txt | grep toto", plutôt que grep toto file.txt ? Quel est l'avantage ?

        Il n'y a pas d'avantage. et même plus d'inconvénient. (création d'un pipe, de 2 process)

        Souvent, c'est plus une méconnaissance ou de flemme
    • [^] # Re: le pipe crée un sous-processus indépendant

      Posté par . Évalué à 1.

      Merci pour l'explication :)

      Ca satisfait ma curiosité intellectuelle et m'évite de tabasser mon ordi (surtout que ça sert à rien et que je devrais plutôt tabasser mon serveur)
  • # Comme ca

    Posté par (page perso) . Évalué à 2.

    gnumdk@flanders:~$ cat p
    #!/bin/bash

    I=0
    while read REF_LINE
    do
    (( i+=1 ))
    echo $i
    done < /etc/fstab

    echo a la fin I=$i

    gnumdk@flanders:~$ bash p
    1
    2
    3
    4
    5
    6
    7
    8
    9
    a la fin I=9
    gnumdk@flanders:~$


    Sinon, tu peux faire comme ca aussi
    commande | ( while read argument
    do
    blah blah
    done

    #les variables de ta boucle sont toujours accessible

    )
    • [^] # Re: Comme ca

      Posté par . Évalué à 1.

      En fait en faisant comme ça ça marche.
      I=-1

      while read ligne
      do
      {
      let I++;
      }
      done < file.txt

      echo "I = "$I;

      Mais pas en faisant comme ça :
      I=-1;

      cat file.txt | while read REF_LINE

      do

      {

      let I++;

      }

      done

      echo "I = "$I;

      mais je sais pas pourquoi :\

      quoi qu'il en soit, merci pour votre aide :D
      • [^] # Re: Comme ca

        Posté par (page perso) . Évalué à 2.

        I=-1;

        cat file.txt | ( while read REF_LINE

        do

        {

        let I++;

        }

        done

        echo "I = "$I;
        )

        Comme ca ca fonctionne!!!
        avec l'utilisation de ( ) , ca te permet de rester dans le processus de la boucle!

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.