Léa-Linux & amis :   LinuxFR   GCU-Squad   GNU
Encore une basherie
Envoyé par: Fanch

Bah à moi aussi bash fait des misères ; quelqu'un serait-il en mesure de m'expliquer ça :


VAR="AAA"

ls | while read rep
do 
  VAR=${rep}
  echo "Dans le while : ${VAR}"
done

echo "Hors while : ${VAR}

et ça me répond :
Dans le while : rep1
Dans le while : rep2
Hors while : AAA

pourquoi VAR n'a pas gardé sa dernière valeur, à savoir rep2 ????? ?-(
m'enfin ?!

------- <br />
La meilleure façon de prédire le futur, c'est de l'inventer ~ Alan Kay

Poste le Tuesday 17 April 2007 11:22:53
Répondre     Citer    
Re: Encore une basherie
Envoyé par: Fanch

Je deviens chèvre :

VAR="AAA"
for rep in `ls`
do
  VAR=${rep}
  echo "Dans le for : ${VAR}"
done

echo "Hors for : ${VAR}

ça répond :
Dans le for : rep1
Dans le for : rep2
Hors for : rep2

aga aga agaga #%b#%b#%b
un problème de pipe ?

------- <br />
La meilleure façon de prédire le futur, c'est de l'inventer ~ Alan Kay

Poste le Tuesday 17 April 2007 11:30:46
Répondre     Citer    
Re: Encore une basherie
Envoyé par: Mochi-Mochi

Salut,

Tout simplement parce que man bash. :-))

Lorsque tu fais un pipe, chaque branche du pipe s'exécute dans un sous-shell et balance sa sortie à la commande suivante. Donc ton while est dans un sous-shell et tout ce qui s'y fait n'affecte pas pas le shell-père.

C'est comme si tu faisais :

VAR="AAA"
for rep in `ls`
do
(
  VAR=${rep}
  echo "Dans le for : ${VAR}"
)
done

echo "Hors for : ${VAR}

Si tu veux t'en convaincre, regarde le nombre de processus sh qui tournent selon qu'on est dans la boucle ou pas :
VAR="AAA"
ps -C sh
ls | while read rep
do
  VAR=${rep}
  echo "Dans le while : ${VAR}"
ps -C sh
done

echo "Hors while : ${VAR}"
ps -C sh


Poste le Tuesday 17 April 2007 12:45:36
Répondre     Citer    
Re: Encore une basherie
Envoyé par: Fanch

c'est bien ce que j'avais suspecté ; mais du coup c'est grave pénible parce que c'est impossible d'utiliser une structure while pour faire ce genre de magouille.

rhalala ! tout ça, ça vaut pas un bon script python !!!

------- <br />
La meilleure façon de prédire le futur, c'est de l'inventer ~ Alan Kay

Poste le Tuesday 17 April 2007 15:02:42
Répondre     Citer    
Re: Encore une basherie
Envoyé par: oudoubah

Citation
Fanch
c'est bien ce que j'avais suspecté ; mais du coup
c'est grave pénible parce que c'est impossible
d'utiliser une structure while pour faire ce genre
de magouille.

rhalala ! tout ça, ça vaut pas un bon script
python !!!

D'où la commande export :
#!/bin/sh

VAR="AAA"
for rep in `ls`
do
  VAR=${rep}
  echo "Dans le for : ${VAR}"
        export VAR
done

echo "Hors for : ${VAR}"

Ah! Rien ne vaut un bon script bash! :-))

Tu as lu les docs. Tu es devenu un informaticien. Que tu le veuilles
ou non. Lire la doc, c'est le Premier et Unique Commandement de
l'informaticien.
-+- TP in: Guide du Linuxien pervers - "L'évangile selon St Thomas"

Poste le Tuesday 17 April 2007 15:10:51
Répondre     Citer    
Re: Encore une basherie
Envoyé par: Fanch

Non non ! ça ne vaudrait que si tu faisais un ls | while ... sinon, ça marche déjà (l'export sert à rien) !

tricheur ! ;-p



------- <br />
La meilleure façon de prédire le futur, c'est de l'inventer ~ Alan Kay

Poste le Tuesday 17 April 2007 16:58:28
Répondre     Citer    
Re: Encore une basherie
Envoyé par: Mochi-Mochi

Non, a priori le patriarcat est de mise en shell : c'est impossible de modifier les définitions du shell-père avec celles d'un fils. C'est un peu normal, puisque tu as un sous processus, c'est comme si tu faisais un appel système sur un script python à partir d'un autre script python, j'imagine que tu ne serais pas très heureux si les variables de l'un et de l'autre partageaient le même espace de nom. ;-)

Après, pour utiliser "| while read" en influeant sur le père, tu peux ruser mais ça dépend ce que tu veux faire... dans l'exemple donné ça n'apporterait rien que des complications.

Poste le Tuesday 17 April 2007 18:11:53
Répondre     Citer    
Re: Encore une basherie
Envoyé par: Fanch

bah en fait ça met en évidence que je ne sais pas travailler avec les références des variables en bash (comme avec des pointeurs en C/C++).
Mais bon, je me formalise pas plus que ça :-)) , bash ne fait pas partie des éléments pour lesquels je suis "tenu" de faire du code propre yawning smiley)

------- <br />
La meilleure façon de prédire le futur, c'est de l'inventer ~ Alan Kay

Poste le Tuesday 17 April 2007 21:06:33
Répondre     Citer    
Re: Encore une basherie
Envoyé par: oudoubah

Pour les pointeurs bash, (c'est pas du C, hein!), voici un exemple :
#!/bin/sh

VAR="AAA"
pointeur=VAR

echo ${VAR}
echo ${!pointeur}

Sinon, pour ton problème, il te faut passer soit par un fichier, soit par des descripteurs de fichiers (style stdout, mais en créer un autre pour).
A avoir des variables qui puissent changer dans des sous-shell, j'utiliserai un fichier contenant les variables, que je modifierais à coup de sed (soyons bourrin), et que je "sourcerais" à chaque fois après les appels aux sous-shell qui modifient les variables.

Tu as lu les docs. Tu es devenu un informaticien. Que tu le veuilles
ou non. Lire la doc, c'est le Premier et Unique Commandement de
l'informaticien.
-+- TP in: Guide du Linuxien pervers - "L'évangile selon St Thomas"

Poste le Tuesday 17 April 2007 22:23:30
Répondre     Citer    
Re: Encore une basherie
Envoyé par: chromosome

Il faut faire ca :

VAR="AAA"

ls | ( while read rep
do 
  VAR=${rep}
  echo "Dans le while : ${VAR}"
done

echo "Hors while : ${VAR}"
)

Avec des parenthèses

Poste le Wednesday 18 April 2007 00:00:23
Répondre     Citer    
Re: Encore une basherie
Envoyé par: Fanch

Citation
oudoubah
A avoir des variables qui puissent changer dans des sous-shell, j'utiliserai un fichier contenant les variables, que je modifierais à coup de sed
(soyons bourrin), et que je "sourcerais" à chaque fois après les appels aux sous-shell qui modifient les variables.
ah pas con ! mais bon, c'est un peu lourdingue aussi donc je vais rester sur le for. Merci pour le ${!pointeur} ! :-)

Citation
chromosome
Avec des parenthèses
ouais d'accord mais bon, tu ne fais que déplacer le problème en intégrant l'ultime echo dans le sous-shell généré par le pipe. Dans mon vrai script, le dernier echo c'est 1400 lignes ... (je porte du dcl d'openvms vers bash et j'ai pas fondamentalement le temps de reprendre la structure des scripts).


------- <br />
La meilleure façon de prédire le futur, c'est de l'inventer ~ Alan Kay

Poste le Wednesday 18 April 2007 00:13:30
Répondre     Citer    
Re: Encore une basherie
Envoyé par: Sve@r

Citation
Fanch
ouais d'accord mais bon, tu ne fais que déplacer
le problème en intégrant l'ultime echo dans le
sous-shell généré par le pipe. Dans mon vrai
script, le dernier echo c'est 1400 lignes

Pas de problème même avec 1400 lignes d'écart

#!/bin/sh

work()
{
    (
        ls | (
                while read ligne
                do
                       <.... traitement de $ligne ....>
                done
                echo "le truc final qu'il faut afficher"
              )
     )
}

<... travail normal de 1400 ligne ...>
work

# ou bien

resultat=`work`

# Fin du script

L'homme qui murmurait à l'oreille des pingouins
[fr.lang.free.fr]

Poste le Wednesday 18 April 2007 14:23:13
Répondre     Citer    

Veuillez vous authentifier auparavant pour commenter.

 

Ce forum !
Encore une basherie
Pour poser vos questions sur les scripts shell, le Perl, le C, etc... Attention : nous ne sommes pas des spécialistes du dev, ce forum est juste pour de petites aides ponctuelles concernant le développement et les outils de développement.

Sauf mention contraire, les documentations publiées sont sous licence Creative-Commons