That obscure feature of (original) sh - having to do with changing exported variables

That obscure feature of (original) sh - having to do with changing exported variables

Post by Kenny McCorma » Fri, 12 Oct 2001 09:27:23



Observe (under Solaris, using original /bin/sh):

$ echo $TERM
VT220
$ TERM=vt100;echo $TERM
vt100
$ exec sh
$ echo $TERM
vt220

This is expected behavior, since I did not export TERM (again) after
changing it.  In fact, steady readers of this newsgroup will recognize that
this was all hashed out a few months ago - where someone pointed out that
this behavior isn't 100% consistent - that scripts that depend on it,
sometimes fail.  Most people's reactions at the time were along the lines
of:
    1) "Modern" version of sh (ksh, bash, Posix shells) don't do this.
    2) It was a misfeature in the first place and you shouldn't rely on it.

Granting all of that, I am still curious about something.  That is,
under what circumstances can it "fail" - that is, have it print out
VT100 in the last step of the above example? (*)  I know that some
cases (well, at least one case) of this exists, but I can't pin the
circumstances.

Any help is appreciated.

(*) Or, to be more precise, have an exec'd (or fork/exec'd) process get the
changed value in its environment.

 
 
 

That obscure feature of (original) sh - having to do with changing exported variables

Post by Derek M. Fly » Fri, 12 Oct 2001 12:36:30



> Observe (under Solaris, using original /bin/sh):

> $ echo $TERM
> VT220
> $ TERM=vt100;echo $TERM
> vt100
> $ exec sh
> $ echo $TERM
> vt220

> This is expected behavior, since I did not export TERM (again) after
> changing it.

...

Thats not the behavior I would expect at all.  Not unless your dotfiles
are resetting your environment.  /bin/sh on Solaris is a POSIX shell, by
the way.  Are you sure the file specified by $ENV doesn't set TERM?  If
so, thats why your TERM is being changed, not because you need to re-export
TERM.

 
 
 

That obscure feature of (original) sh - having to do with changing exported variables

Post by Chris F.A. Johnso » Fri, 12 Oct 2001 13:23:00



Quote:> Observe (under Solaris, using original /bin/sh):

> $ echo $TERM
> VT220
> $ TERM=vt100;echo $TERM
> vt100
> $ exec sh
> $ echo $TERM
> vt220

> This is expected behavior, since I did not export TERM (again) after
> changing it.  In fact, steady readers of this newsgroup will recognize that
> this was all hashed out a few months ago - where someone pointed out that
> this behavior isn't 100% consistent - that scripts that depend on it,
> sometimes fail.  Most people's reactions at the time were along the lines
> of:
>     1) "Modern" version of sh (ksh, bash, Posix shells) don't do this.
>     2) It was a misfeature in the first place and you shouldn't rely on it.

> Granting all of that, I am still curious about something.  That is,
> under what circumstances can it "fail" - that is, have it print out
> VT100 in the last step of the above example? (*)  I know that some
> cases (well, at least one case) of this exists, but I can't pin the
> circumstances.

> Any help is appreciated.

> (*) Or, to be more precise, have an exec'd (or fork/exec'd) process get the
> changed value in its environment.

I missed the discussion you refer to (or my memory is going), but I would
expect your last "echo $TERM" to give "vt100" unless TERM were set in
.profile or /etc/profile (or whatever files /bin/sh sources on
invocation).

However, a comparison of two shell man pages (sh on SunOS 4.1.4 and bash
2.05) shows two different behaviours:

SunOS:
  Environment
     The environment (see environ(5V)) is a  list  of  name-value
     pairs  that is passed to an executed program in the same way
     as a normal argument list.  The  shell  interacts  with  the
     environment in several ways.  On invocation, the shell scans
     the environment and creates a parameter for each name found,
**** giving it the corresponding value.  If the user modifies the ****
**** value of any of these parameters or creates new  parameters, ****
**** none of these affects the environment unless the export com- ****
**** mand is used to bind the shell's parameter to  the  environ- ****
     ment  (see  also `set -a').  A parameter may be removed from
     the environment with the  unset  command.   The  environment
     seen by any executed command is thus composed of any unmodi-
     fied name-value pairs originally  inherited  by  the  shell,
     minus  any pairs removed by unset, plus any modifications or
     additions, all of which must be noted in export commands.

Bash 2.05:

  Environment

     When a program is invoked it is given an array of strings
     called the environment. This is a list of name-value pairs,
     of the form name=value.

     Bash provides several ways to manipulate the environment. On
     invocation, the shell scans its own environment and creates a
     parameter for each name found, automatically marking it for
     export to child processes. Executed commands inherit the
     environment. The export and `declare -x' commands allow
     parameters and functions to be added to and deleted from the
***  environment. If the value of a parameter in the environment     ***
***  is modified, the new value becomes part of the environment,     ***
***  replacing the old. The environment inherited by any executed    ***
***  command consists of the shell's initial environment, whose      ***
***  values may be modified in the shell, less any pairs removed     ***
     by the unset and `export -n' commands, plus any additions via
     the export and `declare -x' commands.

In bash "If the value of a parameter in the environment is modified, the
new value becomes part of the environment, replacing the old" whereas in
the SunOS shell, "If the user modifies the value of any of these
parameters ..., none of these affects the environment unless the export
command is used".

In other words, the behaviour is shell-dependent.

--
    Chris F.A. Johnson                        http://cfaj.freeshell.org
    ===================================================================
    My code (if any) in this post is copyright 2001, Chris F.A. Johnson
    and may be copied under the terms of the GNU General Public License

 
 
 

That obscure feature of (original) sh - having to do with changing exported variables

Post by Casper H.S. Dik - Network Security Engine » Fri, 12 Oct 2001 15:50:37


[[ PLEASE DON'T SEND ME EMAIL COPIES OF POSTINGS ]]


>Granting all of that, I am still curious about something.  That is,
>under what circumstances can it "fail" - that is, have it print out
>VT100 in the last step of the above example? (*)  I know that some
>cases (well, at least one case) of this exists, but I can't pin the
>circumstances.

if you call exort on the variable any time during the current shell
invocation, it will export the new value.

Imported environment variables need to be exported if you change them.
(But you only need to export them once; and it doesn't matter whether it's
before or after setting/changing the variable)

Casper

--
Expressed in this posting are my opinions.  They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.

 
 
 

That obscure feature of (original) sh - having to do with changing exported variables

Post by Paul Egger » Fri, 12 Oct 2001 16:30:30



Quote:> /bin/sh on Solaris is a POSIX shell, by the way.

No it isn't.  For example, Solaris 8 /bin/sh doesn't grok 'set -C', as
POSIX requires.

If you want a POSIX shell on Solaris, you'll have better luck with
/bin/ksh (or with /bin/bash on Solaris 8).

 
 
 

That obscure feature of (original) sh - having to do with changing exported variables

Post by Kenny McCorma » Fri, 12 Oct 2001 20:49:22




>[[ PLEASE DON'T SEND ME EMAIL COPIES OF POSTINGS ]]


>>Granting all of that, I am still curious about something.  That is,
>>under what circumstances can it "fail" - that is, have it print out
>>VT100 in the last step of the above example? (*)  I know that some
>>cases (well, at least one case) of this exists, but I can't pin the
>>circumstances.

>if you call exort on the variable any time during the current shell
>invocation, it will export the new value.

>Imported environment variables need to be exported if you change them.
>(But you only need to export them once; and it doesn't matter whether it's
>before or after setting/changing the variable)

Yup - that's it.  If I start out by doing "export TERM", then subsequent
changes do get exported.  Interesting, because note that the variable is
obvious in the "export state" - or else you would expect its value in
subsequent processes to be null (rather than being the "old" value).  So,
obviously, there are different stages of "export" (maybe it is a 0,1,2
variable, rather than a simple 0,1).

Now, I just have to re-read the man pages and see if it supports this
interpretation.

And, to all of you who thought there was something wrong with my
experimental design or that $ENV or .profile was somehow involved, you can
stay after class and clean the erasers.

 
 
 

That obscure feature of (original) sh - having to do with changing exported variables

Post by Philip Bro » Sat, 13 Oct 2001 01:11:32



Quote:

>If you want a POSIX shell on Solaris, you'll have better luck with
>/bin/ksh (or with /bin/bash on Solaris 8).

or specifically /usr/xpg4/bin/sh, which is the "official" way to do it in
solaris.

--
[Trim the no-bots from my address to reply to me by email!]
[ Do NOT email-CC me on posts. Pick one or the other.]

The word of the day is mispergitude

 
 
 

That obscure feature of (original) sh - having to do with changing exported variables

Post by Darren Dunha » Sat, 13 Oct 2001 10:49:31



Quote:> Observe (under Solaris, using original /bin/sh):
> $ echo $TERM
> VT220
> $ TERM=vt100;echo $TERM
> vt100
> $ exec sh
> $ echo $TERM
> vt220
> This is expected behavior, since I did not export TERM (again) after
> changing it.

Whoaaa.....  stop right there.  What does "after changing it" have to do
with anything?

You don't export a variable's *data*, you export a *variable*.  Whether
you do it before or after setting it is irrelevant.  Since we can't tell
from your post whether it was ever exported in the past, we cannot tell
if the behavior is correct.

# echo $TERM                 (new shell, not exported)
vt100
# TERM=foobar;echo $TERM
foobar
# exec sh
# echo $TERM
vt100                        (not exported, so gets from env)
# export TERM                (exported now)
# echo $TERM
vt100
# TERM=foobar; echo $TERM    (variable modified, but still exported)
foobar
# exec sh
# echo $TERM
foobar                       (picked up).

--

Unix System Administrator                    Taos - The SysAdmin Company
Got some Dr Pepper?                           San Francisco, CA bay area
          < How are you gentlemen!! Take off every '.SIG'!! >

 
 
 

That obscure feature of (original) sh - having to do with changing exported variables

Post by Darren Dunha » Sat, 13 Oct 2001 10:54:02




> Yup - that's it.  If I start out by doing "export TERM", then subsequent
> changes do get exported.  Interesting, because note that the variable is
> obvious in the "export state" - or else you would expect its value in
> subsequent processes to be null (rather than being the "old" value).  So,
> obviously, there are different stages of "export" (maybe it is a 0,1,2
> variable, rather than a simple 0,1).

I'm sorry... I don't understand what you're trying to say there...

There's only one stage of export that I can see.  Can you rephrase it
for me?

The subsequent shell gets the environment, as reported by 'env'.

--

Unix System Administrator                    Taos - The SysAdmin Company
Got some Dr Pepper?                           San Francisco, CA bay area
          < How are you gentlemen!! Take off every '.SIG'!! >

 
 
 

1. Hiding non-sh features from sh

Hi there all.

  Id like to know how to hide non-sh features from sh.

  Consider the following script:

-----------
        #!/bin/ash
        arithmexp=no

        evaluate()
        {
                # Has arithmetic expansion ?
                if [ $arithmexp = yes ] ; then

                        # Yes, use arithmetic expansion
                        echo $(($1))
                else
                        # No, use expr
                        echo `expr $1`
                fi
        }

        evaluate "3 + 2"
-----------

  This runs ok under ash (with arithmexp=no), ksh and bash (both
  with arithmexp=yes) on my Linux box at home. But under SunOS
  her at work (with arithmexp=no) it says:

  syntax error at line 11: `(' unexpected  

  It looks like the shell reads the script, parses it and then
  executes it. Although ash has no arithmetic expansion it
  does not choke on the $((...)) construct but sh does.

  The question: how do I hide non-sh features like the
  arithmetic expansion from sh parsing ?

  Hope this makes sense ...

Juan Carlos---

2. How to access struct ppp?

3. Adding/Changing an exported Shell Variable

4. The OTHER internals book on multiple CPU's

5. Q about obscure sendmail features for sun's 8.6 version

6. Free CDs at MacWorld?

7. An obscure pppd feature. :^|

8. GD+LZW

9. Obscure Zsh feature...

10. Export with variable variable-names?

11. sh variable variables?

12. Setting variables with variables (sh/bash) $it=$bit (in functions

13. Setting variables with variables (sh/bash) [Summary]