PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Forums Hébergement > Forum Serveur - Sécurité et techniques > comp.unix.shell > Bourne Shell: scope of variables in while loop
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
comp.unix.shell Using and programming the Unix shell.

Bourne Shell: scope of variables in while loop

Réponse
 
LinkBack Outils de la discussion
Vieux 26/08/2006, 14h25   #1
Doug Ritschel
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Bourne Shell: scope of variables in while loop

For some reason, I am not able to access variables that were changed in a
while loop, after the while loop finishes. For example:

i=0
echo "this is a test" | while read line
do
i = `expr $i + 1`
done
echo $i

-------------------------------
The echo statement prints 0 rather than 1. Does anyone know why?



  Réponse avec citation
Vieux 26/08/2006, 15h02   #2
Michal Nazarewicz
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Bourne Shell: scope of variables in while loop

"Doug Ritschel" <ritschel@optonline.net> writes:

> i=0
> echo "this is a test" | while read line; do
> i = `expr $i + 1`
> done
> echo $i


The while loop is run in a subshell and it has it's own local
variables so changing them won't change the value of oryginal
variable.

In fact AFAIK the question was answered in FAQ.


--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>--<jid:mina86*jabber.org>--ooO--(_)--Ooo--
  Réponse avec citation
Vieux 26/08/2006, 16h08   #3
Doug Ritschel
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Bourne Shell: scope of variables in while loop


"Michal Nazarewicz" <mina86@tlen.pl> wrote in message
news:87r6z3d27r.fsf@erwin.piotrekn...
> "Doug Ritschel" <ritschel@optonline.net> writes:
>
> > i=0
> > echo "this is a test" | while read line; do
> > i = `expr $i + 1`
> > done
> > echo $i

>
> The while loop is run in a subshell and it has it's own local
> variables so changing them won't change the value of oryginal
> variable.
>
> In fact AFAIK the question was answered in FAQ.
>
>


Why, then , if I run the following, the echo prints 3, which is the number
of lines in the hosts file.

i=0
while read line; do
i = `expr $i + 1`
done < /etc/hosts
echo $i


  Réponse avec citation
Vieux 26/08/2006, 16h30   #4
Doug Ritschel
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Bourne Shell: scope of variables in while loop


"Doug Ritschel" <ritschel@optonline.net> wrote in message
news:8sZHg.206$Y43.108@newsfe09.lga...
>
> "Michal Nazarewicz" <mina86@tlen.pl> wrote in message
> news:87r6z3d27r.fsf@erwin.piotrekn...
> > "Doug Ritschel" <ritschel@optonline.net> writes:
> >
> > > i=0
> > > echo "this is a test" | while read line; do
> > > i = `expr $i + 1`
> > > done
> > > echo $i

> >
> > The while loop is run in a subshell and it has it's own local
> > variables so changing them won't change the value of oryginal
> > variable.
> >
> > In fact AFAIK the question was answered in FAQ.
> >
> >

>
> Why, then , if I run the following, the echo prints 3, which is the number
> of lines in the hosts file.
>
> i=0
> while read line; do
> i = `expr $i + 1`
> done < /etc/hosts
> echo $i
>
>


Found the below answer:

The disadvantage of the pipe-to-while method is that each element in the
pipeline is run in a subshell, so variables set inside the while loop
(for example) won't be set after the loop is complete[*].

find . | {
while read line
do
: whatever
word=${line%% *}
done

: variables set within the loop are still available here, e.g.:
printf "%s\n" "$word"

}



  Réponse avec citation
Vieux 26/08/2006, 17h02   #5
Michal Nazarewicz
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Bourne Shell: scope of variables in while loop

"Doug Ritschel" <ritschel@optonline.net> writes:

> "Michal Nazarewicz" <mina86@tlen.pl> wrote in message
> news:87r6z3d27r.fsf@erwin.piotrekn...
>> "Doug Ritschel" <ritschel@optonline.net> writes:
>>
>> > i=0
>> > echo "this is a test" | while read line; do
>> > i = `expr $i + 1`
>> > done
>> > echo $i

>>
>> The while loop is run in a subshell and it has it's own local
>> variables so changing them won't change the value of oryginal
>> variable.

>
> Why, then , if I run the following, the echo prints 3, which is the
> number of lines in the hosts file.
>
> i=0
> while read line; do i=`expr $i + 1`; done < /etc/hosts
> echo $i


Because there is no need for subshell. In the first while loop you've
used a pipe so shell had to run another process. In the second while
loop you didn't use a pipe but only redirect stdout to be read from
/etc/hosts.

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>--<jid:mina86*jabber.org>--ooO--(_)--Ooo--
  Réponse avec citation
Vieux 26/08/2006, 21h15   #6
Chris F.A. Johnson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Bourne Shell: scope of variables in while loop

On 2006-08-26, Doug Ritschel wrote:
>
> "Michal Nazarewicz" <mina86@tlen.pl> wrote in message
> news:87r6z3d27r.fsf@erwin.piotrekn...
>> "Doug Ritschel" <ritschel@optonline.net> writes:
>>
>> > i=0
>> > echo "this is a test" | while read line; do
>> > i = `expr $i + 1`
>> > done
>> > echo $i

>>
>> The while loop is run in a subshell and it has it's own local
>> variables so changing them won't change the value of oryginal
>> variable.
>>
>> In fact AFAIK the question was answered in FAQ.
>>
>>

>
> Why, then , if I run the following, the echo prints 3, which is the number
> of lines in the hosts file.
>
> i=0
> while read line; do
> i = `expr $i + 1`
> done < /etc/hosts
> echo $i


First, you did not get any output from that script unless you have
an executable named 'i'. You are asking the shell to execute a
command named 'i', with arguments of '=' and '1'; you are not
incrementing a variable. You meant: i=`expr $i + 1` (no spaces
around the equals sign).

Second, you were not running it (with the error fixed) in a Bourne
shell. If you were, you would still have seen '0'. In a Bourne
shell, the redirecion alone is enough to force a subshell.


--
Chris F.A. Johnson, author <http://cfaj.freeshell.org>
Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
===== My code in this post, if any, assumes the POSIX locale
===== and is released under the GNU General Public Licence
  Réponse avec citation
Vieux 27/08/2006, 12h57   #7
Michal Nazarewicz
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Bourne Shell: scope of variables in while loop

"Chris F.A. Johnson" <cfajohnson@gmail.com> writes:

> On 2006-08-26, Doug Ritschel wrote:
>> i=0
>> while read line; do
>> i = `expr $i + 1`
>> done < /etc/hosts
>> echo $i

>
> Second, you were not running it (with the error fixed) in a Bourne
> shell. If you were, you would still have seen '0'. In a Bourne
> shell, the redirecion alone is enough to force a subshell.


Are you sure?

$ cat test.sh
i=0
while read line; do i=$(($i + 1)); done </etc/hosts
echo $i
$ ash test.sh
24
$ bash test.sh
24
$ zsh test.sh
24


Any pointers to standards which support your claim?

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>--<jid:mina86*jabber.org>--ooO--(_)--Ooo--
  Réponse avec citation
Vieux 27/08/2006, 13h43   #8
Stephane CHAZELAS
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Bourne Shell: scope of variables in while loop

2006-08-27, 13:57(+02), Michal Nazarewicz:
> "Chris F.A. Johnson" <cfajohnson@gmail.com> writes:
>
>> On 2006-08-26, Doug Ritschel wrote:
>>> i=0
>>> while read line; do
>>> i = `expr $i + 1`
>>> done < /etc/hosts
>>> echo $i

>>
>> Second, you were not running it (with the error fixed) in a Bourne
>> shell. If you were, you would still have seen '0'. In a Bourne
>> shell, the redirecion alone is enough to force a subshell.

>
> Are you sure?
>
> $ cat test.sh
> i=0
> while read line; do i=$(($i + 1)); done </etc/hosts
> echo $i
> $ ash test.sh
> 24
> $ bash test.sh
> 24
> $ zsh test.sh
> 24
>
>
> Any pointers to standards which support your claim?

[...]

Neither ash, bash or zsh are the Bourne shell. Your ash is not
the original ash as it supports $((...)). You can find a Bourne
shell as the /bin/sh of Solaris or some very old commercial
Unices.

The Bourne shell doesn't have $((...)), and there's no standard
specifying the Bourne shell.

In the Bourne shell, redirection meant fork. Newer shells use
some trick to work around that limitation (they save the
redirected fds (for restauration afterwards) by dupplicating
them on other fds before doing the redirections, which you could
do manually with the Bourne shell this way:
exec 3<&0 < /etc/hosts
while read line
do i=`expr "$i" + 1 3<&-`
done
exec <&3 3<&-
)


--
Stéphane
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 09h31.


Édité par : vBulletin® version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,15247 seconds with 16 queries