Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 Feb 1996 01:25:57 -0500 (EST)
From:      Marc Ramirez <mrami@mramirez.sy.yale.edu>
To:        Archie Cobbs <archie@tribe.com>
Cc:        freebsd-questions@freebsd.org
Subject:   Re: stupid sh tricks
Message-ID:  <Pine.BSF.3.91.960214011708.25905A-100000@mramirez.sy.yale.edu>
In-Reply-To: <199602132231.OAA10024@bubba.tribe.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 13 Feb 1996, Archie Cobbs wrote:

> 
> Hi,
> 
> This is a pretty basic sh(1) question. I apologize that it's not
> FreeBSD specific... but I couldn't seem to find the answer in the
> man page or ftp://rtfm.mit.edu/pub/usenet-by-hierarchy/comp/unix/shell.
> Also, I don't get news right now... ok, enough apologies...
> 
> Consider the following script:
> 
>     #!/bin/sh
> 
>     foo ()
>     {
>       GLOBAL_ONE="foo_one"
>       GLOBAL_TWO="foo_two"
>       while read ARG; do
> 	GLOBAL_TWO=${ARG}
>       done
>       return 0
>     }
> 
>     bar ()
>     {
>       GLOBAL_ONE="bar_one"
>       GLOBAL_TWO="bar_two"
>     }
> 
>     echo before : GLOBAL_ONE=${GLOBAL_ONE} and GLOBAL_TWO=${GLOBAL_TWO}
> 
>     echo "value" | foo
>     echo foo set: GLOBAL_ONE=${GLOBAL_ONE} and GLOBAL_TWO=${GLOBAL_TWO}
> 
>     bar
>     echo bar set: GLOBAL_ONE=${GLOBAL_ONE} and GLOBAL_TWO=${GLOBAL_TWO}
> 
> The output of this script is:
> 
>     before : GLOBAL_ONE= and GLOBAL_TWO=
>     foo set: GLOBAL_ONE= and GLOBAL_TWO=
>     bar set: GLOBAL_ONE=bar_one and GLOBAL_TWO=bar_two
> 
> Why!? Seems like have a "read" in the function foo() changes
> variable scoping or something. This "read" seems to be a very
> broken command... another example:
> 
>     $ cat foo
>     foo-contents
>     $ read VAR < foo
>     $ echo $VAR
>     foo-contents
>     $ VAR=
>     $ echo $VAR
> 
>     $ cat foo | read VAR
>     $ echo $VAR
> 
>     $ exit
> 
> So "read" seems to "know" whether its input is coming from a
> file or a pipe. Is this a bug or a feature? :-)

Feature.  sh handles pipes by forking.  The read statement is being run 
in a child process, the child exits, and then the value is lost. I don't 
know how you would propagate that info backwards... You could get around 
it using fifos, or you could do something like

var="`cat foo`"

if at all possible.  Maybe some fancy trickery with eval.

Marc.

--
If a President doesn't do it to his wife, he'll do it to his country.




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.91.960214011708.25905A-100000>