According to the POSIX specifications eval is a special shell built-in, which should imply that variable assignments specified together with it should remain in effect after the built-in completes. Thus one would expect IFS to be changed after this:
var=$'a\nb c'
$ IFS=$'\n' eval '
for i in $var; do
echo "$i"
done'
a
b c
#!/bin/bash --posix
#!/usr/bin/env dash
#!/usr/bin/env bash
# @(#) s1 Demonstrate IFS setting.
# Section 1, setup, pre-solution.
# Infrastructure details, environment, commands for forum posts.
# Uncomment export command to test script as external user.
# export PATH="/usr/local/bin:/usr/bin:/bin"
set +o nounset
pe() { for i;do printf "%s" "$i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
# C=$HOME/bin/context && [ -f $C ] && . $C eval
version 2>&1 >/dev/null && version =o eval
set -o nounset
pe " posix setting: \"$(set -o | grep -i posix)\""
pe
# Section 2, solution.
pl " Results:"
pe " original: IFS is $(set | grep ^IFS | od -bc)"
var=$'a\nb c'
IFS=$'\n' eval '
pe " before loop: IFS is $(set | grep ^IFS | od -bc)"
for i in $var; do
echo "$i"
done
'
pe " after loop: IFS is $(set | grep ^IFS | od -bc)"
exit 0
The setting stays the same:
% ./s1
OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
Distribution : Debian GNU/Linux 5.0 (lenny)
eval - is a shell builtin [bash]
posix setting: "posix on"
-----
Results:
original: IFS is 0000000 111 106 123 075 047 040 011 012
I F S = ' \t \n
0000010
before loop: IFS is 0000000 111 106 123 075 047 012
I F S = ' \n
0000006
a
b c
after loop: IFS is 0000000 111 106 123 075 047 012
I F S = ' \n
0000006
I think this is what you expected.
The dash and plain bash did not keep the before-loop setting ... cheers, drl
original: IFS is 0000000 111 106 123 075 044 047 040 134 164 134 156 047 012
I F S = $ ' \ t \ n '
0000015
before loop: IFS is 0000000 111 106 123 075 044 047 134 156 047 012
I F S = $ ' \ n '
0000012
a
b c
after loop: IFS is 0000000 111 106 123 075 044 047 134 156 047 012
I F S = $ ' \ n '
Thanks guys.. Mystery solved! I ran it through ksh and dash before but I must have been looking at the wrong thing .... It is a bash-only thing then. I never realized default bash is so much different from POSIX and that you really need to use --posix for it to be compliant (at least the way it is compiled in my distribution)