zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: 3.1.5: eval with exported vars
       [not found] <19981211080558.46630@athenaeum.demon.co.uk>
@ 1998-12-11  9:52 ` Peter Stephenson
  1998-12-11 12:23   ` Andrej Borsenkow
  0 siblings, 1 reply; 4+ messages in thread
From: Peter Stephenson @ 1998-12-11  9:52 UTC (permalink / raw)
  To: zsh-workers

Phil Pennock wrote:
> Trying this:
> % FOO=x eval sh -c 'echo $FOO'
> and then without the eval, it seems the eval loses the auto-export
> functionality, in both 3.0.5 and 3.1.5.  It doesn't appear to be
> documented though.

The workaround is

eval 'FOO=x sh -c '\'echo $FOO'\'

by the way.  (Note all the quotes:  see below.)

> Bug?

I was going to say yes, but it's specifically mentioned in the source
that it does this (exec.c, line 1793 of my current version):

	    if (cmd->vars) {
		/* Export this if the command is a shell function,
		 * but not if it's a builtin.
		 */
		addvars(cmd->vars, is_shfunc);

I think the idea must have been that `builtins don't need values
exported' which, as you've seen, is not true in this case.  The patch
is the simplest fix, and I think it's good enough.

There's something that had me horribly confused (though it's actually
working the way God intended):

% FOO=x eval sh -c 'echo $FOO'
<nothing printed>

That's because eval sees the string "sh -c echo $FOO" and turns this
into sh -c 'echo' 'x', so sh gets an 'echo' command with $0 set to x.
To prove it:

% FOO=x eval sh -c '"echo \$0" $FOO'
x

(why $0 not $1?) so you really need

% FOO=x eval sh -c \''echo $FOO'\'
x

phew.

*** Src/exec.c.eval	Thu Dec 10 11:24:46 1998
--- Src/exec.c	Fri Dec 11 10:14:01 1998
***************
*** 1792,1800 ****
  
  	    if (cmd->vars) {
  		/* Export this if the command is a shell function,
! 		 * but not if it's a builtin.
  		 */
! 		addvars(cmd->vars, is_shfunc);
  		if (errflag) {
  		    restore_params(restorelist, removelist);
  		    lastval = 1;
--- 1792,1802 ----
  
  	    if (cmd->vars) {
  		/* Export this if the command is a shell function,
! 		 * but not if it's a builtin, unless the builtin
! 		 * is an eval.
  		 */
! 		addvars(cmd->vars, is_shfunc ||
! 			(is_builtin && ((Builtin)hn)->funcid == BIN_EVAL));
  		if (errflag) {
  		    restore_params(restorelist, removelist);
  		    lastval = 1;



Peter Stephenson <pws@ibmth.df.unipi.it>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy


^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: PATCH: 3.1.5: eval with exported vars
  1998-12-11  9:52 ` PATCH: 3.1.5: eval with exported vars Peter Stephenson
@ 1998-12-11 12:23   ` Andrej Borsenkow
  1998-12-11 12:45     ` Peter Stephenson
  0 siblings, 1 reply; 4+ messages in thread
From: Andrej Borsenkow @ 1998-12-11 12:23 UTC (permalink / raw)
  To: Peter Stephenson, zsh-workers

>
> I was going to say yes, but it's specifically mentioned in the source
> that it does this (exec.c, line 1793 of my current version):
>
> 	    if (cmd->vars) {
> 		/* Export this if the command is a shell function,
> 		 * but not if it's a builtin.
> 		 */
> 		addvars(cmd->vars, is_shfunc);
>

I just checked it with two versions of sh and ksh and all behave the same
way as zsh. I think, it is also correct.

Variable assignment does no _export_ them. It makes them available in
execution environment of command to be executed. It is just, that if command
executes in separate process, the only way to make them available is to
export them ...

In case of eval, FOO is set, but not exported, which is correct - and hence,
spawned process does not see it.

But zsh takes one thing wrong. Variable assignment made before special
builtins, remain in effect after builtin finishes (see POSIX and Single Unix
and Unix 98). eval is special builtin, but see

bor@itsrm2:/tools/var%> FOO=x eval 'echo $FOO'
x
bor@itsrm2:/tools/var%> echo $FOO

But as I understand, your patch blindly exports variable for every builtin?

> I think the idea must have been that `builtins don't need values
> exported' which, as you've seen, is not true in this case.  The patch
> is the simplest fix, and I think it's good enough.
>

Again, FOO=x cmd does not export it at all. something strange here.

> There's something that had me horribly confused (though it's actually
> working the way God intended):
>
> % FOO=x eval sh -c 'echo $FOO'
> <nothing printed>
>
> That's because eval sees the string "sh -c echo $FOO" and turns this
> into sh -c 'echo' 'x', so sh gets an 'echo' command with $0 set to x.
> To prove it:
>
> % FOO=x eval sh -c '"echo \$0" $FOO'
> x
>
> (why $0 not $1?) so you really need
>
> % FOO=x eval sh -c \''echo $FOO'\'
> x

Wow! May wonders never cease :)

bor@itsrm2:/tools/var%> FOO=x eval sh -c '"echo $FOO"'
x
bor@itsrm2:/tools/var%> echo $FOO

bor@itsrm2:/tools/var%>

Still wrong - FOO disappears.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PATCH: 3.1.5: eval with exported vars
  1998-12-11 12:23   ` Andrej Borsenkow
@ 1998-12-11 12:45     ` Peter Stephenson
  1998-12-11 13:27       ` Andrej Borsenkow
  0 siblings, 1 reply; 4+ messages in thread
From: Peter Stephenson @ 1998-12-11 12:45 UTC (permalink / raw)
  To: zsh-workers

"Andrej Borsenkow" wrote:
> But as I understand, your patch blindly exports variable for every builtin?

No, just eval, which is a peculiar case because you really don't know
what it's going to do.  The workaround I gave (assignment after the
eval) is really the best way of doing it.  You can certainly argue
it's not right to have eval as a special case, but I'd say exporting
it rather than just setting it is the safest here.

> bor@itsrm2:/tools/var%> FOO=x eval sh -c '"echo $FOO"'
> x
> bor@itsrm2:/tools/var%> echo $FOO
> 
> Still wrong - FOO disappears.

This is supposed to depend on the setting of POSIXBUILTINS.  It does
seem to work for me.  It's annoying there's yet another option, but I
think it's mainly for setting for for ksh emulation rather than `real'
zsh users.

Possibly the patch I sent should have a !isset(POSIXBUILTINS) wrapper?

-- 
Peter Stephenson <pws@ibmth.df.unipi.it>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy


^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: PATCH: 3.1.5: eval with exported vars
  1998-12-11 12:45     ` Peter Stephenson
@ 1998-12-11 13:27       ` Andrej Borsenkow
  0 siblings, 0 replies; 4+ messages in thread
From: Andrej Borsenkow @ 1998-12-11 13:27 UTC (permalink / raw)
  To: Peter Stephenson, zsh-workers

>
> "Andrej Borsenkow" wrote:
> > But as I understand, your patch blindly exports variable for
> every builtin?
>
> No, just eval, which is a peculiar case because you really don't know
> what it's going to do.

Sorry. But I don't think this is needed. Currently it behaves exactly as it
should.

bor@itsrm2:~smbsrc/source%> FOO=x eval sh -c 'echo $FOO'

bor@itsrm2:~smbsrc/source%> FOO=x eval 'sh -c echo $FOO'

Both are correct as you explained. The string after -c is just "echo" It is
funny, but so is it.

bor@itsrm2:~smbsrc/source%> FOO=x eval sh -c "echo $FOO"

Correct. $FOO is expanded when the whole is first read.

bor@itsrm2:~smbsrc/source%> FOO=x eval 'sh -c "echo $FOO"'
x

Correct. eval gets 'sh -c "$FOO"', expands $FOO to x, so it amounts to sh -c
'echo x'.

bor@itsrm2:~smbsrc/source%> FOO=x eval 'sh -c "echo \$FOO"'

Correct. It expands to sh -c 'echo $FOO' and FOO is _not_ exported (and
should not).

bor@itsrm2:~smbsrc/source%> FOO=x eval 'FOO=bar sh -c "echo \$FOO"'
bar

If you really want to export something to command excuted in eval.

Why is it wrong. It is clean and consistent.

 The workaround I gave (assignment after the
> eval) is really the best way of doing it.  You can certainly argue
> it's not right to have eval as a special case, but I'd say exporting
> it rather than just setting it is the safest here.
>

Why? See above - you always can export it if needed.

>
> This is supposed to depend on the setting of POSIXBUILTINS.

'course you are right.

>
> Possibly the patch I sent should have a !isset(POSIXBUILTINS) wrapper?
>

Possibly, we don't need the patch at all?

/andrej


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~1998-12-11 13:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <19981211080558.46630@athenaeum.demon.co.uk>
1998-12-11  9:52 ` PATCH: 3.1.5: eval with exported vars Peter Stephenson
1998-12-11 12:23   ` Andrej Borsenkow
1998-12-11 12:45     ` Peter Stephenson
1998-12-11 13:27       ` Andrej Borsenkow

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).