Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 24/05/2018, à 08:42

Brice Jeunieaux

Subtilité de Bash dans son fonctionnement ? (Tableaux associatifs)

Bonjour / bonsoir,

maîtrisant maintenant, après un bon apprentissage, le fonctionnement des tableaux associatifs en Bash, je les utilise afin de stocker mes données.
Jusque là, tout va bien. Lorsque dans un fichier, je déclare mon tableau, je le remplis, puis affiche les valeurs des cases que j'ai remplies, tout ça à la suite et de manière "rapprochée" dans mon script, tout se passe correctement dans le meilleur des mondes.

Par contre, lorsque je décide de le déclarer, puis de le remplir (ces deux parties de code étant proches de quelques lignes), mais que je décide de ne les appeler que bien plus tard, je fais une rencontre du troisième type : il me dit que mon tableau ne contient qu'une case dont l'indice est "0".


Ma question est : "Pourquoi est-ce que tout fonctionne correctement lorsque les trois parties de code pour déclarer, remplir et afficher les cases d'un tableau sont rapprochées, alors que tout part en vrille lorsque je décide d'afficher bien plus tard ? Et surtout, qu'est-ce qui se passe dans le Bash ?".
Merci d'avance pour votre aide. smile

Hors ligne

#2 Le 24/05/2018, à 10:01

pingouinux

Re : Subtilité de Bash dans son fonctionnement ? (Tableaux associatifs)

Bonjour,
Pas facile de deviner sans voir le code…
Le tableau est-il rempli et utilisé dans le même shell ?
N'as-tu pas une variable de même nom que le tableau dans la partie intermédiaire ?

Hors ligne

#3 Le 24/05/2018, à 12:11

Brice Jeunieaux

Re : Subtilité de Bash dans son fonctionnement ? (Tableaux associatifs)

Concrètrement, dans un fichier de test, où j'ai testé les parties de codes mises bout à bout, j'obtiens :

pageActuelle=1;
nbPagesBD=4 ;
nbLignesAffichees=15 ;

for (( a=1 ; a<=$nbPagesBD ; a++ )) do
	for (( b=$(($nbLignesAffichees*$(($a-1))+1)) ; b<=$(($nbLignesAffichees*$a)) ; b++ )) do
		for (( c=2 ; c<=7 ; c++ )) do
			tableauGeneral["Page$a,LD$b,Champ$c"]=$(grep -G '^l'$(($b))x crepeBD.txt | cut -d \; -f $c)
  		done
	done
done

for (( a=$(( $(( $(( $pageActuelle-1 )) * $nbLignesAffichees )) +1 )) ; a<=$(( $pageActuelle * $nbLignesAffichees )) ; a++ )) do
	for ((c=2 ; c<= 7 ; c++ )) do
		echo -e "\${tableauGeneral[\"Page$pageActuelle,LD$a,Champ$c\"]} : ${tableauGeneral["Page$pageActuelle,LD$a,Champ$c"]}"
	done
done

Ce script de test fonctionne correctement et m'affiche bien les résultats que je veux (ici, toutes les cases du tableau dont la clé commence par 'Page1').
Dans ces cases là, j'ai bien les données voulues. Pas de problème là-dessus.


Dans le deuxième cas où les parties de codes sont éloignées, celles-ci sont dans des fonctions, appelées.
J'ai bien entendu vérifié que mes variables (dont tableaux) soient globales, sur tout le script, et oui, elles le sont, donc je ne pense pas que ce soit un problème dû aux fonctions. Voici mon code, dans le deuxième cas, grosso modo :

traitementTableauGeneral() {
	
	for (( a=1 ; a<=$nbPagesBD ; a++ )) do
		for (( b=$(($nbLignesAffichees*$(($a-1))+1)) ; b<=$(($nbLignesAffichees*$a)) ; b++ )) do
			for (( c=2 ; c<=7 ; c++ )) do
				tableauGeneral["Page$a,LD$b,Champ$c"]=$(grep -G '^l'$(($b))x crepeBD.txt | cut -d \; -f $c)
  			done
		done
	done
	
}

traitementTableauGeneral ;



###          Bien après dans le programme...          ###



affichage() {						#Affichage de l'intégralité des infos que l'utilisateur doit voir

clear

for (( a=$(( $(( $(( $pageActuelle-1 )) * $nbLignesAffichees )) +1 )) ; a<=$(( $pageActuelle * $nbLignesAffichees )) ; a++ )) do
	for ((c=2 ; c<= 7 ; c++ )) do
		tput cup $(($a+4-$(($pageActuelle-1))*15)) 5  ; echo -e "${tableauGeneral["Page$pageActuelle,LD$a,Champ$c"]}"
		tput cup $(($a+4-$(($pageActuelle-1))*15)) 24 ; echo -e "${tableauGeneral["Page$pageActuelle,LD$a,Champ$c"]}"
		tput cup $(($a+4-$(($pageActuelle-1))*15)) 50 ; echo -e "${tableauGeneral["Page$pageActuelle,LD$a,Champ$c"]}"
		tput cup $(($a+4-$(($pageActuelle-1))*15)) 66 ; echo -e "${tableauGeneral["Page$pageActuelle,LD$a,Champ$c"]}"
		tput cup $(($a+4-$(($pageActuelle-1))*15)) 81 ; echo -e "${tableauGeneral["Page$pageActuelle,LD$a,Champ$c"]}"
	done
done

}

affichage ;

Donc voilà, ce qu'il faut retenir, c'est que dans le cas de la deuxième manière, mon tableau est bien global et non-prisonnier de la fonction d'où il est créé et construit. Si n'importe qui aurait ne serait-ce qu'une idée, celle-ci est la bienvenue. smile

Hors ligne

#4 Le 24/05/2018, à 12:22

credenhill

Re : Subtilité de Bash dans son fonctionnement ? (Tableaux associatifs)

hello
je ne vois pas de declare -A ... pour déclarer un tabeau  associatif

Hors ligne

#5 Le 24/05/2018, à 12:53

pingouinux

Re : Subtilité de Bash dans son fonctionnement ? (Tableaux associatifs)

La fonction ne gêne pas.
Exemple

declare -A tab

remplissage(){
   tab[t1]=10
   tab[t2]=20
}

affichage(){
   for k in "${!tab[@]}"; do echo "=$k=>${tab[$k]}="; done
}

remplissage
affichage

qui donne ce résultat

=t1=>10=
=t2=>20=

Tu peux utiliser la méthode bestiale, mais qui a fait ses preuves : imprimer le tableau à différents endroits du script, pour voir à quel moment il diparaît.

Hors ligne

#6 Le 24/05/2018, à 14:47

Watael

Re : Subtilité de Bash dans son fonctionnement ? (Tableaux associatifs)

for (( a=$(( $(( $(( $pageActuelle-1 )) * $nbLignesAffichees )) +1 ));

les premières parenthèses "ouvrent" déjà un évaluation arithmétique, il n'est donc pas nécessaire d'en "ouvrir" d'autres :

for (( a=(pageActuelle -1)*nbLignesAffichees +1; ...

Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#7 Le 24/05/2018, à 21:22

Brice Jeunieaux

Re : Subtilité de Bash dans son fonctionnement ? (Tableaux associatifs)

credenhill a écrit :

hello
je ne vois pas de declare -A ... pour déclarer un tabeau  associatif

Je viens de voir que je l'ai oublié au moment de copier-coller dans cette conversation, mais ne t'inquiètes pas, il est bel et bien présent dans le code du fichier test, et ça marche bien, donc ce n'est pas un problème de déclaration.


pingouinux a écrit :
affichage(){
   for k in "${!tab[@]}"; do echo "=$k=>${tab[$k]}="; done
}

Je vais tester cette syntaxe, ainsi que la méthode à la sauvage, je redis quoi demain dans cette conversation, cela m'arrangerait beaucoup qu'en changeant de syntaxe, tout se mette à fonctionner normalement (dans mon fichier définitif). De plus, c'est une syntaxe très simple, à la KISS.


Watael a écrit :
for (( a=$(( $(( $(( $pageActuelle-1 )) * $nbLignesAffichees )) +1 ));

les premières parenthèses "ouvrent" déjà un évaluation arithmétique, il n'est donc pas nécessaire d'en "ouvrir" d'autres :

for (( a=(pageActuelle -1)*nbLignesAffichees +1; ...

Je savais pas, ça, merci, ça va me clarifier le code tout ça ^^.

Hors ligne

#8 Le 25/05/2018, à 06:50

MicP

Re : Subtilité de Bash dans son fonctionnement ? (Tableaux associatifs)

Bonjour

Plutôt que de faire refaire le même calcul plusieurs fois à chaque tour de boucle for,
je pense qu'il vaut mieux ne le faire qu'une seule fois en utilisant des variables :

traitementTableauGeneral() {
	
	for (( a=1 ; a<=nbPagesBD ; a++ )) do
                min=$((nbLignesAffichees*(a-1)+1))
                max=$((nbLignesAffichees*a))
		for (( b=min ; b<=max ; b++ )) do
			for (( c=2 ; c<=7 ; c++ )) do
				tableauGeneral["Page$a,LD$b,Champ$c"]=$(grep -G '^l'${b}x crepeBD.txt | cut -d \; -f $c)
  			done
		done
	done
	
}

traitementTableauGeneral ;



###          Bien après dans le programme...          ###



affichage() {						#Affichage de l'intégralité des infos que l'utilisateur doit voir

clear

min=$(((pageActuelle-1)*nbLignesAffichees+1))
max=$((pageActuelle*nbLignesAffichees))
for (( a=min ; a<=max ; a++ )) do
        ligne=$(((a+4-pageActuelle-1)*15))
	for ((c=2 ; c<= 7 ; c++ )) do
		tput cup $ligne 5  ; echo -e "${tableauGeneral["Page$pageActuelle,LD$a,Champ$c"]}"
		tput cup $ligne 24 ; echo -e "${tableauGeneral["Page$pageActuelle,LD$a,Champ$c"]}"
		tput cup $ligne 50 ; echo -e "${tableauGeneral["Page$pageActuelle,LD$a,Champ$c"]}"
		tput cup $ligne 66 ; echo -e "${tableauGeneral["Page$pageActuelle,LD$a,Champ$c"]}"
		tput cup $ligne 81 ; echo -e "${tableauGeneral["Page$pageActuelle,LD$a,Champ$c"]}"
	done
done

}

affichage ;

Dernière modification par MicP (Le 06/06/2018, à 11:47)

Hors ligne