Forum Programmation.shell Passage de variable depuis une boucle

Posté par  .
Étiquettes : aucune
0
7
jan.
2005

Bonsoir à tous,

Voici un petit script problématique, il est censé trier le contenu d'un fichier texte.

end_seq="PK_WO_YES_NO WORKORDER_IDX"
line_cnt=0

compare_files ()
{
if [ -e exctract.log ]
then
cat < exctract.log | while true
do
read temp_line2
if [ "$temp_line2" = "" ]; then break; fi

tablespace2=$temp_line2
echo tablespace= "$tablespace"
echo tablespace2= "$tablespace2"
if [ "$tablespace" = "$tablespace2" ]
then
already_exists="1"
break
else
already_exists="0"
fi
done
echo already_exists= $already_exists
return $already_exists
fi
}

cat < hwi1_tlbspc.log | while true
do
read temp_line
let "line_cnt++"


set -- $temp_line
table=$1
tablespace=$2
if [ "$line_cnt" -eq 1 ]; then echo $tablespace > exctract.log; fi

already=`compare_files`

echo already= $already

if [ $already -eq 0 ]
then
echo $tablespace >> exctract.log
fi

if [ "$temp_line" = "$end_seq" ]; then break; fi
done


A l'execution j'obtiens une jolie série de :
already= tablespace= WORKORDER_IDX tablespace2= ALERT already_exists=
UStablespaces.sh: line 52: [: too many arguments

En résumé, la variable already_exists dans la fonction n'est pas transmise à la sortie de la boucle dans laquelle elle est initialisée.
Quelqu'un peut me dire ce que je manque ?

Merci d'avance...

  • # référence

    Posté par  (site web personnel) . Évalué à 1.

    "return $already..." se trouve dans $? après exécution de la fonction, pour être logique, tu devrais faire un return 0 à la fin, pour dire que tout s'est bien passé.
    `compare_files` = "$already..." si tu fais un 'echo $already...' dans ta fonction.

    http://www.mcwalter.org/technology/shell/functions.html
  • # Precision

    Posté par  . Évalué à 1.

    cat < $FILE_EXT | while true
    		do
    			read temp_line2
    			if [ "$temp_line2" = "" ]; then break; fi
    			tablespace2=$temp_line2
    			echo tablespace fr= "$tablespace"
    			echo tablespace2= "$tablespace2"
    			if [ "$tablespace" = "$tablespace2" ]
    			then
    				already_exists="1"
    				echo already_exists 28= $already_exists 
    				break
    			else
    				already_exists="0"
    				echo already_exists 32= $already_exists
    			fi
    			echo already_exists 34= $already_exists
    		done
    		echo already_exists 36= $already_exists
    	fi
    	echo already_exists 39= $already_exists
    
    Renvoie : tablespace fr= ALERT_IDX tablespace2= ALERT already_exists 32= 0 already_exists 34= 0 already_exists 36= already_exists 39= already_exists 61= 0 tablespace fr= ALERT_IDX tablespace2= ALERT already_exists 32= 0 already_exists 34= 0 tablespace fr= ALERT_IDX tablespace2= ALERT_IDX already_exists 28= 1 already_exists 36= 0 already_exists 39= 0 already_exists 61= 0 tablespace fr= ALERT_IDX tablespace2= ALERT already_exists 32= 0 already_exists 34= 0 tablespace fr= ALERT_IDX tablespace2= ALERT_IDX already_exists 28= 1 already_exists 36= 0 already_exists 39= 0 already_exists 61= 0 Donc c'est bien already_exists qui ne passe pas correctement la sortie de la boucle... Je comprends pas mais alors pas du tout...
    • [^] # Re: Precision

      Posté par  . Évalué à 1.

      Excusez moi, comme ça ce sera plus lisible :

      tablespace fr= ALERT_IDX
      tablespace2= ALERT
      already_exists 32= 0
      already_exists 34= 0
      already_exists 36=
      already_exists 39=
      already_exists 61= 0

      tablespace fr= ALERT_IDX
      tablespace2= ALERT
      already_exists 32= 0
      already_exists 34= 0
      tablespace fr= ALERT_IDX
      tablespace2= ALERT_IDX
      already_exists 28= 1
      already_exists 36= 0
      already_exists 39= 0
      already_exists 61= 0

      tablespace fr= ALERT_IDX
      tablespace2= ALERT
      already_exists 32= 0
      already_exists 34= 0
      tablespace fr= ALERT_IDX
      tablespace2= ALERT_IDX
      already_exists 28= 1
      already_exists 36= 0
      already_exists 39= 0
      already_exists 61= 0
  • # une piste

    Posté par  . Évalué à 2.

    Il me semble que c'est une histoire de processus fils créé par le pipe. Ta boucle tourne dans un processus fils, avec son propre environnement qui ne peut être récupéré par le père. Une paire de parenthèses bien placées doit pouvoir forcer l'exécution dans un seul process mais je ne sais plus très bien comment...
    Creuse dans cette direction.
    • [^] # Re: une piste

      Posté par  . Évalué à 1.

      Merci pour ta réponse...

      Exactement ça :)

      Voici la réponse que j'avais obtenu dans un autre forum:

      Piege classique de read avec les pipes... La partie gauche de ton pipe (la boucle while) est exécutée dans un sous-process (forcément, comment veux-tu qu'il fasse le cat et le read en même temps sinon). Donc already_exists est une variable d'environement dans ton sous process. Après ta boucle while, tu es à nouveau dans le process père. Evidemment already_exists n'a pas été modifié dans ce process : un process fils n'a pas accès à l'environnement de son père.

      Un facon de contourner ce "problème" est de mettre toute la partie du script qui utilise already_exists entre parenthèses, de maninère à ce que toutte cette partie soit exécutée dans le même process fils. Ouvre la parenthèse avant le while, ferme la avant le return.

Suivre le flux des commentaires

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