What should this do?: $SHELL -c 'HOME=foo echo $HOME'

What should this do?: $SHELL -c 'HOME=foo echo $HOME'

Post by Ric » Wed, 27 May 1992 10:45:59



Is there a POSIX comment on this?  {,k,z}sh return /blah/blah/user,
bash returns foo.  I prefer bash's behaviour, but consensus seems to
be the other way.  Anything in the standard?

Rick.

 
 
 

What should this do?: $SHELL -c 'HOME=foo echo $HOME'

Post by Ric » Wed, 27 May 1992 11:30:53



>Subject: What should this do?: $SHELL -c 'HOME=foo echo $HOME'

>Is there a POSIX comment on this?  {,k,z}sh return /blah/blah/user,
>bash returns foo.  I prefer bash's behaviour, but consensus seems to
>be the other way.  Anything in the standard?
>Rick.

Before I get a flood of replies telling me I left out the semicolon :-),
the construct
        var=value cmd
is supposed to modify and export the environment variable `var' only for
the invocation of `cmd'.  That is, while `cmd' is running, $var == value,
and when it exits, $var will have its original value.  My most common use
for this is debubbing.  A program checks for a DEBUG environment variable,
modifying it's actions accordingly.  To do a single debug run, I just
do
        DEBUG= cmd

The original posting was concerned with when variable substition is done
on a command line.  In {,k,z}sh, substitution is done before the fork
which sets up the subshell environment, while in bash it appears to be
done after.  My question is: which behaviour is standard?

Rick.

 
 
 

What should this do?: $SHELL -c 'HOME=foo echo $HOME'

Post by Duncan Sincla » Wed, 27 May 1992 22:26:49



>Subject: What should this do?: $SHELL -c 'HOME=foo echo $HOME'

>Is there a POSIX comment on this?  {,k,z}sh return /blah/blah/user,
>bash returns foo.  I prefer bash's behaviour, but consensus seems to
>be the other way.  Anything in the standard?

I don't know about posix, but I think that sh,ksh, and zsh get it right.

Quote:>Before I get a flood of replies telling me I left out the semicolon :-),

Of course, putting in the semi-colon will change the behaviour to be as you
wish it to be.

Here's why...

Quote:>The original posting was concerned with when variable substition is done
>on a command line.  In {,k,z}sh, substitution is done before the fork
>which sets up the subshell environment, while in bash it appears to be
>done after.  My question is: which behaviour is standard?

No, the substitution is done in the subshell, but parameter expansion
on $HOME is being done before "environment augmentation" is done.

I prefer the 'sh' behavour, because it is _the_ standard, upon
which other standards (posix) must be built.

No doubt the bash people will now tell me I'm wrong.  (I'm a zsh-user!)

With a semi-colon, the HOME=foo becomes a seperate command, and so
the shell variable is modified before it goes on to parse the echo command.

--


University of Glasgow               |..!mcsun!ukc!uk.ac.glasgow.dcs!sinclair
     No! Not the .sig virus again!  I thought I had removed it.

 
 
 

What should this do?: $SHELL -c 'HOME=foo echo $HOME'

Post by Duncan Sincla » Wed, 27 May 1992 22:53:57


I hate following up my own articles...


>No, the substitution is done in the subshell, but parameter expansion
>on $HOME is being done before "environment augmentation" is done.

Here's a puzzle that I don't understand, to do with what I've called
here "environment augmentation" and built-ins in both sh, and zsh...

$ xxx=ug echo $xxx .
.
$ echo $xxx .
ug .

This struck me as wrong, so I tried this...

$ yyy=ug /bin/echo $yyy .
.
$ echo $yyy .
.

The "."s are there just to fill what would otherwise be blank lines.

So, why does the variable get set for a built-in command, but not otherwise?
Or to put the question another way, why does it get set for
built-in commands, when experience tells me it shouldn't?

It makes some sense that it is because the shell doesn't need to
fork to do built-ins that the variable is getting set/updated when
it shouldn't.

Perhaps this should go into a new "sh programming considered harmful".

What does bash do for this?  Is there an analogous feature in rc?

--


University of Glasgow               |..!mcsun!ukc!uk.ac.glasgow.dcs!sinclair
           ---  Rave Culture: Don't techno for an answer.  ---

 
 
 

What should this do?: $SHELL -c 'HOME=foo echo $HOME'

Post by Byron Rakitz » Thu, 28 May 1992 01:33:21



Quote:>Here's a puzzle that I don't understand, to do with what I've called
>here "environment augmentation" and built-ins in both sh, and zsh...
>$ xxx=ug echo $xxx .
>.
>$ echo $xxx .
>ug .
>So, why does the variable get set for a built-in command, but not otherwise?
>Or to put the question another way, why does it get set for
>built-in commands, when experience tells me it shouldn't?

I would call it a bug.

Quote:>What does bash do for this?  Is there an analogous feature in rc?

rc has local assignments that go away at the end of ANY kind of command.

Byron.

 
 
 

What should this do?: $SHELL -c 'HOME=foo echo $HOME'

Post by Geoff Cla » Wed, 03 Jun 1992 22:45:55



>Subject: What should this do?: $SHELL -c 'HOME=foo echo $HOME'

>Is there a POSIX comment on this?  {,k,z}sh return /blah/blah/user,
>bash returns foo.  I prefer bash's behaviour, but consensus seems to
>be the other way.  Anything in the standard?

The (draft) standard requires /blah/blah/user.  The order things
happen in is as follows:

    1.  Words containing variable assignments and redirections are
        saved for processing in steps 3 & 4.

    2.  The remaining words are expanded.

    3.  Redirections are performed.

    4.  Variable assignments are expanded prior to assigning the
        value.

Steps 3 & 4 may be reversed for commands specified as being built-ins,
but not for any other commands (such as echo) that the shell chooses to
implement as built-ins.

BTW, the value of HOME after this command has completed must be
/blah/blah/user.  For specified built-ins it must be foo, but since
echo is not specified as a built-in it must behave as a normal command
regardless of whether it is implemented as a built-in.

[The above information is taken from an XPG4 draft, but since XPG4 has
adopted POSIX.2 it should be the same.]
--

UniSoft Limited, London, England.   Tel: +44 71 729 3773   Fax: +44 71 729 3273

 
 
 

1. 'echo "some text" |read foo' results in empty $foo

Hi!

In a script that I'm working on, I do something like this:

#!/bin/sh
echo "this is some text" |read foo bar baz
echo "the foo variable is: ${foo}"           # should be 'this'
echo "the bar variable is: ${bar}"           # should be 'is'
echo "the baz variable is: ${baz}"           # should be 'some text'

However, the output leaves no doubt that the three variables are unset.

TFM says:

     read name ...
          One line is read from the standard input and, using the
          internal  field separator, IFS (normally space or tab),
          to delimit word boundaries, the first word is  assigned
          to  the first name, the second word to the second name,
          and so forth, with leftover words assigned to the  last
          name.   Lines can be continued using \newline.  Charac-
          ters other than newline can be quoted by preceding them
          with a backslash.  These backslashes are removed before
          words are assigned to names, and no  interpretation  is
          done  on the character that follows the backslash.  The
          return code is 0, unless an EOF is encountered.

So I'm really not sure why it doesn't work. This is /bin/sh under Solaris
2.6, but of course I want the solution to be portable.

I could do something like

foo=`echo "this is some text" | awk '{ print $1 }'`
bar=`echo "this is some text" | awk '{ print $2 }'`

and so on... but that's both ugly and wasteful.

Replies sent directly to me will be summarized for the newsgroup.

Happy Hunting, -Chris

2. dup, /dev/fd, and other philosophical questions

3. foo=X%XY%Z; echo ${foo//X/w} works;echo ${foo//%%/p} NotWhatIwant

4. Telnet in 4.3

5. Can't NFS Mount /home/stu on /home/stu

6. booting with only 2MB memory

7. help: won't create home directories in /home

8. Newcomer

9. jlg058@home.com, tlg62@home.com, egglectric@home.com

10. 3c900, 3c59x on RH5.2 - trying to install @home - can't 'Ping' DNS

11. Users having probs logging into Linux system, get '/home/...' doesn't exist.

12. I've deleted /home - is there anything that can be done..

13. Patch for `echo foo | cat /proc/self/fd/0' bug