How do I correctly run a few commands with an altered value of the IFS variable (to change the way field splitting works and how "$*" is handled), and then restore the original value of IFS?
I know I can do
(
IFS='my value here'
my-commands here
)
to localize the change of IFS to the sub-shell, but I don't really want to start a sub-shell, especially not if I need to change or set the values of variables that needs to be visible outside of the sub-shell.
I know I can use
saved_IFS=$IFS; IFS='my value here'
my-commands here
IFS=$saved_IFS
but that seems to not restore IFS correctly in the case that the original IFS was actually unset.
Looking for answers that are shell agnostic (but POSIX).
Clarification: That last line above means that I'm not interested in a bash-exclusive solution. In fact, the system I'm using most, OpenBSD, does not even come with bash installed at all by default, and bash is not a shell I use for anything much other than to answer questions on this site. It's much more interesting to see solutions that I may use in bash or other POSIX-like shells without making an effort to write non-portable code.
bashlike in all shells with scoping, you'd rather uselocal(though it works best with shells with static scoping or withzsh'sprivateinstead (not that you'd use$IFSinzsh)) . The output of bash'sdeclare -pis not always safe forevaling.evalon anything that has been quoted with anything other than the single-quote based approaches there (and even then, it's best to avoid evaling arbitrary data if that can be avoided)declare -pwithin a single Bash script would be a problem? It seems to focus on differences between shells, and mentions a number of different ways for producing quoted versions of a variable, so it's rather hard to pick up what issue you're referring to.declaretoo. A bit like with theunset IFS [ -n "${save+set}" ] && IFS=$save;case below (it's exactly the same workaround of course, since in the other direction you can justdeclare -p IFS 2> /dev/null)IFS=“Xy“ command