Possible bug with tee or variable scope ??

Possible bug with tee or variable scope ??

Post by Chri » Thu, 29 Jun 2006 09:16:10



It seems that tee can influence the scope of a variable.  This script
below shows a variable not changing when tee is used and changing (as
expected) when tee is not used:

#!/bin/ksh

Name="Init"

change_name ()
        {
        echo "   Fn before: $Name."
        Name="Changed"
        echo "   Fn after : $Name."
        }

echo "Before tee  : $Name."
change_name | tee /dev/null
echo "After tee   : $Name!"
change_name
echo "After no tee: $Name."

Output from HP-UX, Linux and Solaris:

Before tee  : Init.
   Fn before: Init.
   Fn after : Changed.
After tee   : Init!
   Fn before: Init.
   Fn after : Changed.
After no tee: Changed.

 
 
 

Possible bug with tee or variable scope ??

Post by Chris F.A. Johnso » Thu, 29 Jun 2006 09:41:10



> It seems that tee can influence the scope of a variable.  This script
> below shows a variable not changing when tee is used and changing (as
> expected) when tee is not used:

> #!/bin/ksh

> Name="Init"

> change_name ()
>         {
>         echo "   Fn before: $Name."
>         Name="Changed"
>         echo "   Fn after : $Name."
>         }

> echo "Before tee  : $Name."
> change_name | tee /dev/null
> echo "After tee   : $Name!"
> change_name
> echo "After no tee: $Name."

> Output from HP-UX, Linux and Solaris:

> Before tee  : Init.
>    Fn before: Init.
>    Fn after : Changed.
> After tee   : Init!
>    Fn before: Init.
>    Fn after : Changed.
> After no tee: Changed.

    The elements of a pipeline are executed in different subshells;
    the changes made in any of them are not visible to the
    parent shell, except in ksh.

    In ksh, the last element of a pipeline is executed in the calling
    shell, which as you have discovered, it not necessarily what is
    wanted.

--
   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

 
 
 

Possible bug with tee or variable scope ??

Post by Chri » Thu, 29 Jun 2006 11:28:12


Thanks Chris,
We see exactly the same behavour with a borne (sh) parent as well on
the all of different flavors/shells. Could this then be a ksh thing??
(the sub shells may be ksh on hp-ux, bash on Linux , borne on Solaris
etc or all sh ...ie no ksh to been seen)
And if the tee is spawned off in a subshell (or not, say in ksh) one
would expect that variable definitions in the parent would not be
effected
Chris


> > It seems that tee can influence the scope of a variable.  This script
> > below shows a variable not changing when tee is used and changing (as
> > expected) when tee is not used:

> > #!/bin/ksh

> > Name="Init"

> > change_name ()
> >         {
> >         echo "   Fn before: $Name."
> >         Name="Changed"
> >         echo "   Fn after : $Name."
> >         }

> > echo "Before tee  : $Name."
> > change_name | tee /dev/null
> > echo "After tee   : $Name!"
> > change_name
> > echo "After no tee: $Name."

> > Output from HP-UX, Linux and Solaris:

> > Before tee  : Init.
> >    Fn before: Init.
> >    Fn after : Changed.
> > After tee   : Init!
> >    Fn before: Init.
> >    Fn after : Changed.
> > After no tee: Changed.

>     The elements of a pipeline are executed in different subshells;
>     the changes made in any of them are not visible to the
>     parent shell, except in ksh.

>     In ksh, the last element of a pipeline is executed in the calling
>     shell, which as you have discovered, it not necessarily what is
>     wanted.

> --
>    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

 
 
 

Possible bug with tee or variable scope ??

Post by Jon LaBadi » Thu, 29 Jun 2006 12:58:40



> Thanks Chris,
> We see exactly the same behavour with a borne (sh) parent as well on
> the all of different flavors/shells. Could this then be a ksh thing??
> (the sub shells may be ksh on hp-ux, bash on Linux , borne on Solaris
> etc or all sh ...ie no ksh to been seen)
> And if the tee is spawned off in a subshell (or not, say in ksh) one
> would expect that variable definitions in the parent would not be
> effected
> Chris



>>> It seems that tee can influence the scope of a variable.  This script
>>> below shows a variable not changing when tee is used and changing (as
>>> expected) when tee is not used:

>>> #!/bin/ksh

>>> Name="Init"

>>> change_name ()
>>>         {
>>>         echo "   Fn before: $Name."
>>>         Name="Changed"
>>>         echo "   Fn after : $Name."
>>>         }

>>> echo "Before tee  : $Name."
>>> change_name | tee /dev/null
>>> echo "After tee   : $Name!"
>>> change_name
>>> echo "After no tee: $Name."

>>> Output from HP-UX, Linux and Solaris:

>>> Before tee  : Init.
>>>    Fn before: Init.
>>>    Fn after : Changed.
>>> After tee   : Init!
>>>    Fn before: Init.
>>>    Fn after : Changed.
>>> After no tee: Changed.
>>     The elements of a pipeline are executed in different subshells;
>>     the changes made in any of them are not visible to the
>>     parent shell, except in ksh.

>>     In ksh, the last element of a pipeline is executed in the calling
>>     shell, which as you have discovered, it not necessarily what is
>>     wanted.

The ksh comment is distracting Chris' point.

Run by itself, change_name, a function, is run by the parent shell
thus changes made to the variable name are made in the parent.

Run into a pipe, not just a pipe to tee, change_name will be run
by a child shell and changes to the variable name happen in the
child, not in the parent.

 
 
 

Possible bug with tee or variable scope ??

Post by Stephane CHAZELA » Fri, 30 Jun 2006 04:29:01


2006-06-27, 20:41(-04), Chris F.A. Johnson:
[...]

Quote:>     The elements of a pipeline are executed in different subshells;
>     the changes made in any of them are not visible to the
>     parent shell, except in ksh.

Except in zsh and some versions of ksh, and most of the sh of
commercial Unices (which are generally ksh88s or ksh88 based
shells).

Quote:>     In ksh, the last element of a pipeline is executed in the calling
>     shell, which as you have discovered, it not necessarily what is
>     wanted.

[...]

Only with the AT&T versions of ksh (and the zsh ksh emulation)
not with the public domain ksh based ones.

And of course, if the last element of the pipeline is an
external command, it is executed in a different process whatever
the shell.

--
Stphane

 
 
 

Possible bug with tee or variable scope ??

Post by Stephane CHAZELA » Fri, 30 Jun 2006 04:37:56


2006-06-27, 17:16(-07), Chris:
Quote:> It seems that tee can influence the scope of a variable.  This script
> below shows a variable not changing when tee is used and changing (as
> expected) when tee is not used:

> #!/bin/ksh

> Name="Init"

> change_name ()
>         {
>         echo "   Fn before: $Name."
>         Name="Changed"
>         echo "   Fn after : $Name."
>         }

> echo "Before tee  : $Name."
> change_name | tee /dev/null
> echo "After tee   : $Name!"
> change_name
> echo "After no tee: $Name."

[...]

What you could do is:

{
  {
    echo "Before tee  : $Name." # goes to stdout
    change_name >&3 # goes to tee
    echo "After tee   : $Name!"
    change_name
    echo "After no tee: $Name."

  } 3>&1 >&4 4>&- | tee some files

Quote:} 4>&1

Note that zsh has built in support for the tee functionality:

echo foo >&1 > some-file

outputs foo\n both to stdout and to some-file (setopt nomultios
to disable it). And "echo foo" is not started in a subshell (zsh
spawns a background process that reads the output of "echo foo"
via a pipe and tees it to both stdout and some-file, just as |tee
does)

--
Stphane