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
Vieux 27/08/2006, 14h29   #9
Michal Nazarewicz
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Bourne Shell: scope of variables in while loop

Stephane CHAZELAS <this.address@is.invalid> writes:

> Neither ash, bash or zsh are the Bourne shell. [...] You can find
> a Bourne shell as the /bin/sh of Solaris [...]


You're right; I've checked that on SunOS 5.10 and it've printed 0.

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


I get more and more confused as far as standards are concerned. Some
time ago I've downloaded "The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition" and checked all my scripts whether the
conform to that standard and now it appears they will all crush and
burn on some unix platforms.


--
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, 14h43   #10
Stachu 'Dozzie' K.
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Bourne Shell: scope of variables in while loop

On 27.08.2006, Michal Nazarewicz <mina86@tlen.pl> wrote:
> Stephane CHAZELAS <this.address@is.invalid> writes:
>
>> Neither ash, bash or zsh are the Bourne shell. [...] You can find
>> a Bourne shell as the /bin/sh of Solaris [...]

>
> You're right; I've checked that on SunOS 5.10 and it've printed 0.
>
>> The Bourne shell doesn't have $((...)), and there's no standard
>> specifying the Bourne shell.

>
> I get more and more confused as far as standards are concerned. Some
> time ago I've downloaded "The Open Group Base Specifications Issue 6
> IEEE Std 1003.1, 2004 Edition" and checked all my scripts whether the
> conform to that standard and now it appears they will all crush and
> burn on some unix platforms.


Yeap. But they will crush on platforms which doesn't conform to
standard (by default). On Solaris POSIX/SUS conformant shell exists as
/usr/xpg4/bin/sh.

--
<Kosma> Niektórzy lubi± dozziego...
<Kosma> Oczywi¶cie szanujemy ich.
Stanislaw Klekot
  Réponse avec citation
Vieux 27/08/2006, 15h07   #11
Stephane CHAZELAS
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Bourne Shell: scope of variables in while loop

2006-08-27, 15:29(+02), Michal Nazarewicz:
> Stephane CHAZELAS <this.address@is.invalid> writes:
>
>> Neither ash, bash or zsh are the Bourne shell. [...] You can find
>> a Bourne shell as the /bin/sh of Solaris [...]

>
> You're right; I've checked that on SunOS 5.10 and it've printed 0.
>
>> The Bourne shell doesn't have $((...)), and there's no standard
>> specifying the Bourne shell.

>
> I get more and more confused as far as standards are concerned. Some
> time ago I've downloaded "The Open Group Base Specifications Issue 6
> IEEE Std 1003.1, 2004 Edition" and checked all my scripts whether the
> conform to that standard and now it appears they will all crush and
> burn on some unix platforms.

[...]

Those standards specify the POSIX sh which is based on a subset
of ksh which is itself based on the Bourne shell.

sh over the time was a Thomson shell, then a Bourne shell, then
a POSIX shell. Where before they were implementations, now it is
a standard, and several sh implementations (bash, ksh, new
ashes...) implement that standard.

--
Stéphane
  Réponse avec citation
Vieux 27/08/2006, 15h11   #12
Michal Nazarewicz
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut UNIX standard (was: Bourne Shell: scope of variables in while loop)

"Stachu 'Dozzie' K." <dozzie@dynamit.im.pwr.wroc.pl.nospam> writes:

> On 27.08.2006, Michal Nazarewicz <mina86@tlen.pl> wrote:
>> I get more and more confused as far as standards are concerned. Some
>> time ago I've downloaded "The Open Group Base Specifications Issue 6
>> IEEE Std 1003.1, 2004 Edition" and checked all my scripts whether the
>> conform to that standard and now it appears they will all crush and
>> burn on some unix platforms.

>
> Yeap. But they will crush on platforms which doesn't conform to
> standard (by default). On Solaris POSIX/SUS conformant shell exists as
> /usr/xpg4/bin/sh.


But still the standard I've pointed says /bin/sh must conform which
make sens as one put '#!/bin/sh' at the beginning of a script to run
it in conforming shell and it seems like it'll run in non-conforming
shell under Solaris 10.

It seems like I end up on a platform where conforming shell exists
but's it located in non-standard location so I cannot use it anyway.

--
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, 15h22   #13
Stephane CHAZELAS
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: UNIX standard (was: Bourne Shell: scope of variables in while loop)

2006-08-27, 16:11(+02), Michal Nazarewicz:
> "Stachu 'Dozzie' K." <dozzie@dynamit.im.pwr.wroc.pl.nospam> writes:
>
>> On 27.08.2006, Michal Nazarewicz <mina86@tlen.pl> wrote:
>>> I get more and more confused as far as standards are concerned. Some
>>> time ago I've downloaded "The Open Group Base Specifications Issue 6
>>> IEEE Std 1003.1, 2004 Edition" and checked all my scripts whether the
>>> conform to that standard and now it appears they will all crush and
>>> burn on some unix platforms.

>>
>> Yeap. But they will crush on platforms which doesn't conform to
>> standard (by default). On Solaris POSIX/SUS conformant shell exists as
>> /usr/xpg4/bin/sh.

>
> But still the standard I've pointed says /bin/sh must conform which
> make sens as one put '#!/bin/sh' at the beginning of a script to run
> it in conforming shell and it seems like it'll run in non-conforming
> shell under Solaris 10.


No those standards don't say that sh must be in /bin or anywhere
else. They actually don't specify the #! mechanism, and say that
if a script begins with #!, then the behavior is "unspecified"

> It seems like I end up on a platform where conforming shell exists
> but's it located in non-standard location so I cannot use it anyway.


That's a big problem, indeed, and has been discussed many times
in this group.


--
Stéphane
  Réponse avec citation
Vieux 27/08/2006, 16h03   #14
Michal Nazarewicz
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: UNIX standard [SOLVED]

Stephane CHAZELAS <this.address@is.invalid> writes:

>> It seems like I end up on a platform where conforming shell exists
>> but's it located in non-standard location so I cannot use it anyway.

> That's a big problem, indeed, and has been discussed many times
> in this group.


I'll go check the archives then. Thanks for all the replies.

--
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, 16h15   #15
Jon LaBadie
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Bourne Shell: scope of variables in while loop

Stephane CHAZELAS wrote:
> 2006-08-27, 15:29(+02), Michal Nazarewicz:
>> Stephane CHAZELAS <this.address@is.invalid> writes:
>>
>>> Neither ash, bash or zsh are the Bourne shell. [...] You can find
>>> a Bourne shell as the /bin/sh of Solaris [...]

>> You're right; I've checked that on SunOS 5.10 and it've printed 0.
>>
>>> The Bourne shell doesn't have $((...)), and there's no standard
>>> specifying the Bourne shell.

>> I get more and more confused as far as standards are concerned. Some
>> time ago I've downloaded "The Open Group Base Specifications Issue 6
>> IEEE Std 1003.1, 2004 Edition" and checked all my scripts whether the
>> conform to that standard and now it appears they will all crush and
>> burn on some unix platforms.

> [...]
>
> Those standards specify the POSIX sh which is based on a subset
> of ksh which is itself based on the Bourne shell.
>
> sh over the time was a Thomson shell, then a Bourne shell, then
> a POSIX shell. Where before they were implementations, now it is
> a standard, and several sh implementations (bash, ksh, new
> ashes...) implement that standard.
>


Gee, no Mashey shell in there

What does POSIX/OpenGroup have to say about redirection of shell
control structures and special commands? Probably nothing or
'implementation defined'.

bash seems to standout among the three "major" Bourne evolutions,
bash, zsh, and ksh, in treating redirection caused by the redirection
operators differently than that caused by the pipe operator.

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

s=foobar
read s < /etc/hosts
echo $s

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

s=foobar
cat /etc/hosts | read s
echo $s

$ ksh ./testscript
33
# Internet host table
33
# Internet host table

$ zsh ./testscript
33
# Internet host table
33
# Internet host table

$ bash ./testscript
33
# Internet host table
0
foobar
  Réponse avec citation
Vieux 27/08/2006, 16h42   #16
Sven Mascheck
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Bourne Shell: scope of variables in while loop

Stephane CHAZELAS wrote:

> You can find a Bourne shell as the /bin/sh of Solaris
> or some very old commercial Unices.


or in SCO OpenServer or Tru64 or UnixWare or in the Heirloom project.
  Réponse avec citation
Vieux 27/08/2006, 18h36   #17
Stephane CHAZELAS
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Bourne Shell: scope of variables in while loop

2006-08-27, 11:15(-04), Jon LaBadie:
[...]
>> sh over the time was a Thomson shell, then a Bourne shell, then
>> a POSIX shell. Where before they were implementations, now it is
>> a standard, and several sh implementations (bash, ksh, new
>> ashes...) implement that standard.
>>

>
> Gee, no Mashey shell in there


That was simplified, you may want to insert as well the
different evolutions of the Bourne shell (addition of functions,
different variants on different OSes...)

> What does POSIX/OpenGroup have to say about redirection of shell
> control structures and special commands? Probably nothing or
> 'implementation defined'.


It's specified. It should behave the bash/ksh way, not the
Bourne way.

> bash seems to standout among the three "major" Bourne evolutions,
> bash, zsh, and ksh, in treating redirection caused by the redirection
> operators differently than that caused by the pipe operator.


That's something different. parts of a pipeline are run
concurrently, so have to be run in different processes. zsh,
AT&T ksh run the rightmost part in the current shell process,
contrary to bash, ash or pdksh or the Bourne shell where every
part is in children processes. POSIX says that one shouldn't
assume that either part is run on a subshell or not, so that
both bash and AT&T ksh are conformant.

--
Stéphane
  Réponse avec citation
Vieux 27/08/2006, 19h43   #18
Jon LaBadie
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Bourne Shell: scope of variables in while loop

Stephane CHAZELAS wrote:
> 2006-08-27, 11:15(-04), Jon LaBadie:

[...]
>
>> bash seems to standout among the three "major" Bourne evolutions,
>> bash, zsh, and ksh, in treating redirection caused by the redirection
>> operators differently than that caused by the pipe operator.

>
> That's something different. parts of a pipeline are run
> concurrently, so have to be run in different processes. zsh,
> AT&T ksh run the rightmost part in the current shell process,
> contrary to bash, ash or pdksh or the Bourne shell where every
> part is in children processes. POSIX says that one shouldn't
> assume that either part is run on a subshell or not, so that
> both bash and AT&T ksh are conformant.
>


Though I've certainly had scripts using pipes on the output of a
control structure, apparently I never attempted to use any of the
control structure's local environment later in the script. Good
to know that limitation.

Not that I didn't believe you , but I tested to confirm.
  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 17h18.


Édité par : vBulletin® version 3.7.3
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 ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,25090 seconds with 26 queries