Précédent   Forum des professionnels en informatique > Systèmes > Linux > Applications > Shell
Shell Vos questions sur l'utilisation des commandes shell
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 21/10/2011, 16h18   #1
Membre confirmé
 
Inscription : avril 2008
Messages : 188
Détails du profil
Informations forums :
Inscription : avril 2008
Messages : 188
Points : 222
Points : 222
Par défaut Portée des variables en ksh

Bonjour,

J'ai simplifié mon code à l'extrême pour bien mettre en évidence mon problème (d'où le uuoc).
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/ksh
 
function _TTW_test
{
    typeset isOk=0
    echo "1. $$ isOk='${isOk}'"
 
    typeset line
 
    # Check each non empty line of the file
    #egrep -v '^[ \t]*(#|$)' | while read line ; do
 
    cat | while read line ; do
            echo "Check failed for line: '${line}'"
            echo "2a. $$ isOk='${isOk}'"
            isOk=1
            echo "2b. $$ isOk='${isOk}'"
    done
    echo "3. $$ isOk='${isOk}'"
 
    return ${isOk}
}
 
echo "foo\nbar" | _TTW_test
dont le résultat est:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
$ echo $KSH_VERSION
@(#)PD KSH v5.2.14 99/07/13.2
 
$ ./test-typeset-while.ksh 
1. 6889 isOk='0'
Check failed for line: 'foo'
2a. 6889 isOk='0'
2b. 6889 isOk='1'
Check failed for line: 'bar'
2a. 6889 isOk='1'
2b. 6889 isOk='1'
3. 6889 isOk='0'
Si je laisse le "cat |" ou si je le remplace par le "egrep" commenté, j'obtiens systématiquement '0' en sortie de boucle au lieu du '1' attendu.

C'est uniquement lorsque je le supprime complètement que j'obtiens '1'.

Quelqu'un peut-il m'expliquer ce qui m'apparaît comme un mystère... à moins que ce ne soit un bug du ksh!

Merci d'avance pour vos explications.

)jack(
jack-ft est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/10/2011, 17h05   #2
Expert Confirmé Sénior
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 071
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 071
Points : 4 154
Points : 4 154
Bonjour,

ce n'est pas un bug (faut pas rêver ); le pipe (|) ouvre un sous-shell, donc, les variables, qui sont affectées dans le sous-shell, n'existent pas dans le shell parent.
Code :
1
2
3
4
$ echo -e 'foo\nbar\nbaz' | while read line; do [ "$line" = foo ] && maBelleVar="$line"; done; echo "$maBelleVar"

$ echo -e 'foo\nbar\nbaz' | { while read line; do [ "$line" = foo ] && maBelleVar="$line"; done; echo "$maBelleVar";}
foo
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/10/2011, 18h11   #3
Membre confirmé
 
Inscription : avril 2008
Messages : 188
Détails du profil
Informations forums :
Inscription : avril 2008
Messages : 188
Points : 222
Points : 222
Citation:
Envoyé par N_BaH Voir le message
Bonjour,

ce n'est pas un bug (faut pas rêver ); le pipe (|) ouvre un sous-shell, donc, les variables, qui sont affectées dans le sous-shell, n'existent pas dans le shell parent.
Code :
1
2
3
4
$ echo -e 'foo\nbar\nbaz' | while read line; do [ "$line" = foo ] && maBelleVar="$line"; done; echo "$maBelleVar"

$ echo -e 'foo\nbar\nbaz' | { while read line; do [ "$line" = foo ] && maBelleVar="$line"; done; echo "$maBelleVar";}
foo
Merci d'avoir répondu!
Pour un bug, ça me paraissait un peu gros!
C'est bien parce que je soupçonnais quelque chose de ce genre que j'ai pris la précaution d'imprimer le numéro de process $$. Or, comme tu peux le constater dans les traces, il ne varie pas d'un iota (6889 dans l'exemple).
Dois-je en conclure qu'un sous-shell peut avoir le même PID que son père???
Sinon, j'ai contourné le problème à peu près de la même façon que toi (en faisant les grep avant l'appel de la fonction).
)jack(
jack-ft est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/10/2011, 19h44   #4
Expert Confirmé Sénior
 
Avatar de Sve@r
 
Homme Frédéric
Ingénieur développement logiciels
Inscription : février 2006
Messages : 3 055
Détails du profil
Informations personnelles :
Nom : Homme Frédéric
Âge : 44
Localisation : France, Oise (Picardie)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : février 2006
Messages : 3 055
Points : 4 934
Points : 4 934
Citation:
Envoyé par jack-ft Voir le message
C'est bien parce que je soupçonnais quelque chose de ce genre que j'ai pris la précaution d'imprimer le numéro de process $$. Or, comme tu peux le constater dans les traces, il ne varie pas d'un iota (6889 dans l'exemple).
Dois-je en conclure qu'un sous-shell peut avoir le même PID que son père???
En fait, le terme "sous-shell" ne signifie pas "nouveau processus". Avec le pipe, le shell instancie un nouveau "lui-même" mais reste dans le processus courant.

Exemple
Code bash :
1
2
3
4
5
6
7
#!/bin/sh
i=5
(
    i=6
    echo $i $$
)
echo $i $$
Malgré les parenthèses qui instancient un nouveau contexte (preuve en est que la variable i reste inchangée en fin de parenthèses), le pid ($$) reste le même...

Toutefois ce qui est étonnant c'est que tu es en ksh alors que j'avais remarqué il y a qq années (quand je bossais sous Solaris) que cela ne se produisait pas en ksh

Exemple
Code bash :
1
2
3
4
5
6
7
#!/bin/sh
i=18
cat /etc/passwd |while read line
do
    i=`expr $i + 1`
done
echo $i

Ce code produit un résultat différent en shell (il affiche 18) alors qu'en ksh (sous Solaris) il affiche le nb de lignes du fichier /etc/passwd + 18. Il semblerait qu'en ksh (Solaris), la nouvelle instance conserve les variables
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit.
Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant.
Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation.
Dr. Adrian Rogers, 1931
Sve@r est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 25/10/2011, 15h14   #5
Membre confirmé
 
Inscription : avril 2008
Messages : 188
Détails du profil
Informations forums :
Inscription : avril 2008
Messages : 188
Points : 222
Points : 222
pour toutes les réponses.
Je clos
)jack(
jack-ft est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/12/2011, 00h14   #6
Membre Expert
 
Avatar de jlliagre
 
Inscription : juin 2007
Messages : 967
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juin 2007
Messages : 967
Points : 1 370
Points : 1 370
En fait, si, il s'agit bien d'un "bug" de pdksh dans le sens ou ce dernier ne reproduit pas le comportement du vrai ksh qui place le dernier élément d'un "pipeline"dans le shell courant, contrairement à bash par exemple qui lui choisit le premier.
__________________
ɹǝsn *sıɹɐlos*
jlliagre est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 07h41.


 
 
 
 
Partenaires

Hébergement Web