bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: The correct way to use "for" without polluting the environment


From: Stephane Chazelas
Subject: Re: The correct way to use "for" without polluting the environment
Date: Sun, 8 Mar 2015 21:44:39 +0000
User-agent: Mutt/1.5.21 (2010-09-15)

2015-03-07 16:46:52 -0600, Alan Wild:
> I'm really curious to see if anyone else offers better ideas, but the ways
> I've done this are
> 
> 1) exactly what you propose.
> 
> 2) use a subshell (parantheses):
> 
> $ ( for x in a b c; { echo $x; } )
> a
> b
> c
> $ typeset -p x
> bash: typeset: x: not found
> 
> 3) use a function and declare x local to the function
> 
> $ function f() { local x; for x; { echo "$x"; }; }
> $ f a b c
> a
> b
> c
> $ typeset -p x
> bash: typeset: x: not found
[...]

Another solution:

$ x=1
$ x= eval 'for x in 2 3 4; do :; done'
$ echo "$x"
1

That won't work in POSIX mode though:

$ set -o posix
$ x= eval 'for x in 2 3 4; do :; done'
$ echo "$x"
4

eval being a special builtin, variable passed that way are
required to retain their value when the command returns.

You can remove the "special" attribute with "command".

$ x= command eval 'for x in 5 6 7; do :; done'
$ echo "$x"
4

BTW, to get back on topic:

$ bash --norc -o posix
bash-4.3$ unset zzz
bash-4.3$ zzz=x eval
bash-4.3$ env | grep zzz
zzz=x

ksh93, zsh (in sh emulation), dash, mksh, the Bourne shell (the
port of opensolaris' to Linux at least) do retain the value of
zzz after eval has returned but don't export it to the
environment. They don't export it within the evaled code either.

$ ksh -c 'zzz=x eval "env | grep zzz"'
$

yash behaves like bash.

If I interpret the POSIX spec correctly, the variable should
*not* be exported in those cases (though it's not very clear):

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01

SUSv4> If no command name results, or if the command name is a
SUSv4> special built-in or function, variable assignments shall
SUSv4> affect the current execution environment. Otherwise, the
SUSv4> variable assignments shall be exported for the execution
SUSv4> environment of the command and shall not affect the current
SUSv4> execution environment except as a side-effect of the
SUSv4> expansions performed in step 4.

For functions, mksh, yash and zsh behave like bash (again,
against POSIX it would seem) in:

$ bash -c 'f() { env | grep zzz; }; zzz=x f'
zzz=x


-- 
Stephane




reply via email to

[Prev in Thread] Current Thread [Next in Thread]