On Thu, Oct 22, 2026 at 11:23:35 +0200, Michel Verdier wrote:
> On 2026-10-21, Greg Wooledge wrote:
> 
> >     IFS=:
> >     [[ ":${x[*]}:" =~ ":$i:" ]] ...
> >     unset IFS
> 
> Would it be safer to restore IFS ?
> With something like
> 
>   OLDIFS=$IFS
>   IFS=:
>   ...
>   IFS=$OLDIFS
> 
> or using local if within a function

Using local is good, yes.  You could even wrap this in a function so
that local becomes available.

Both "unset IFS" and "IFS=$OLDIFS" make assumptions that are not going
to be true universally.  Mine assumes that IFS was originally in its
default state, and that you want to continue being in the default
state afterward.  Unsetting IFS is operationally equivalent to
setting IFS to its default value of $' \t\n' (just easier to type).

Yours assumes that IFS *had* a prior value, and had not been unset.
If IFS was unset beforehand, then IFS=$OLDIFS will assign the empty
string to IFS, which is very different from unsetting it.

So, both of those are potentially wrong, and using local within a
function (even if it's a lambda created just for this purpose) is
definitely the safest approach.

If you ever need to do this sort of thing in POSIX sh, where local is
not yet mandated, saving IFS will need two steps: you'll need to check
whether IFS is currently unset, as well as tracking its current value
(if any).  Then, for the restoration, you will once again need to check
whether you should unset IFS, or restore its previous value.  This
could be done using one variable, or two variables, but either way it
will require at least two separate steps.  This should work:

saveIFS() {
    if test "${IFS+set}"; then
        _ifs=$IFS
    else
        unset _ifs
    fi
}   

restoreIFS() {
    if test "${_ifs+set}"; then
        IFS=$_ifs
    else
        unset IFS
    fi
}

Obviously it can be squeezed into fewer lines, but I wrote it in this
style for clarity.

Reply via email to