Variable remise à zero, pourquoi ?

Résolu
Bonjour,
j'ai le code suivant
find $dir1 -type f |while read file 
do :
   export flag_l=0
   find $dir2  -name "`basename "$file"`"  | while read file2
   do :
      if (( $flag_l > 0 )) ;then echo "multiple file name";fi
      (( flag_l=$flag_l+1 ))
      if [ "$file2" = "" ]
	then :
	      echo "$file non copier"
	else
	    diff "$file" "$file2"
	fi
#echo $flag_l
   done
echo $flag_l " 0 !!!!???"
   if (( $flag_l == 0 )) 
    then echo "$file non copier;";fi
done

flag_ l vaut toujours 0 à la sortie de la deuxième boucle, alors qu'il ne devrait pas.
comprend pas.



--
La vrai soumission c'est quand les esclaves s'inquiètent du cours du coton.
Char Snipeur

5 réponses

  1. Contributeur
    Salut,

    Parce qu'un
    pipe
    induit un
    sous-shell
    , et deux imbriqués, je n'ose même pas imaginer ;-\

    while read file 
    do
    ...
    done < $(find $dir1 -type f)
    1. Contributeur
      Merci Zipe. Je me doutais bien d'une merde dans ce gout là. Mais normalement, le export est conservé dans les sous shell. Non ?
      Sinon, une autre solution. Le but étant de savoir si le find ligne 4 a retourné une valeur ou non.
      En dernier recours j'utiliserai un fichier plutôt qu'une variable, mais c'est la plaie.
      1. Contributeur
        Mais normalement, le export est conservé dans les sous shell. Non ?
        Le problème chez toi c'est qu'il y a un second pipe, et qu'il faudrait alors exporter à nouveau ta variable ;-\
    2. Contributeur
      Bon, en attendant, je fait
      echo '0'>flag_l
      et ça fonctionne.
      C'est de la bidouille, mais je ne vois pas comment me dépatouiller de ça.
      1. Contributeur
        Salut,

        Le contenu du répertoire :
        $ tree
        .
        |-- foo.sh
        |-- titi
        | |-- fich1
        | |-- fich2
        | |-- fich3
        | `-- fich4
        `-- toto
        |-- fich1
        |-- fich2
        |-- fich3
        |-- fich4
        `-- fichier

        2 directories, 10 files

        Le contenu du script
        cat foo.sh
        :
        #!/bin/bash
        
        #set -x
        
        dir1="toto"
        dir2="titi"
        
        while read file 
        do 
           flag_l="0"
           while read file2
           do 
              if (( ${flag_l} > 0 )) ;then echo "multiple file name";fi
              (( flag_l++ ))
              if [ "${file2}" = "" ]
         then
               echo "${file} non copier"
         else
                    echo "diff ${file} || ${file2}"
             diff "${file}" "${file2}"
         fi
           done < <(find ${dir2}  -name "$(basename ${file})")
        echo ${flag_l} " 0 !!!!???"
           if (( ${flag_l} == 0 )) 
            then echo "${file} non copier;";fi
        done < <(find ${dir1} -type f)


        L'exécution :
        $ ./foo.sh 
        0 0 !!!!???
        toto/fichier non copier;
        diff toto/fich4 || titi/fich4
        1c1
        < Bonjour la life
        ---
        > Bonjour toi
        1 0 !!!!???
        diff toto/fich3 || titi/fich3
        1c1
        < Bonjour la life
        ---
        > Bonjour toi
        1 0 !!!!???
        diff toto/fich2 || titi/fich2
        1c1
        < Bonjour la life
        ---
        > Bonjour la vie
        1 0 !!!!???
        diff toto/fich1 || titi/fich1
        1 0 !!!!???

        ☮ Zen my nuggets ☯
        Faites un geste pour l'environnement, fermez vos fenêtres et adoptez un manchot. <('')
        1. Contributeur
          Merci Zipe, je ne connaissais pas "<<" sous cette forme là. Je faissais "<<EOF" en général, pour mettre des commandes en ligne.
          D'ailleur, c'est
          <<
          ou
          < <
          ?
          En fait, tu execute le find dans un sous-shell (utilisation de paraenthèse) et l'entrée est redirigée vers le while à la manière d'un pipe. C'est ça ?
          1. Contributeur
            D'ailleur, c'est
            <<
            ou
            < <
            ?
            Le second avec un espace entre les chevrons (
            < <(commande...)
            ). En fait le premier est une redirection et le second fait partie intégrante de ce qu'on appelle une "substitution de processus", en voici d'ailleurs l'explication.

            Extrait du man bash :

            Substitution de processus
            La substitution de processus n'est disponible que sur les systèmes acceptant le
            mécanisme des tubes nommés (FIFO) ou la méthode /dev/fd de noms de fichiers. Elle
            prend la forme <(liste) ou >(liste). La liste de processus est exécutée avec son
            entrée ou sa sortie connectée à une FIFO ou à un fichier dans /dev/fd. Le nom de ce
            fichier est passé en argument à la commande qui sera exécutée comme résultat de
            cette substitution. Si on utilise la forme >(liste), l'écriture dans le fichier
            fournira des entrées pour la liste. Si la forme <(liste) est utilisée, le fichier
            passe en argument devra être lu pour obtenir la sortie de la liste.

            Sur les systèmes qui le permettent, la substitution de processus est effectuée
            simultanément au développement des paramètres et variables, à la substitution de
            commande et au développement arithmétique.
            Ce qui devrait répondre à ta seconde question ;-)
          2. Contributeur
            merci, je ne connaissait pas.
            Des fois, c'est un peu du charabia pour moi les man. Là, typiquement.