Before I answer, here's a warning: changing
IFS tends to have really confusing effects. There are a few places where it's relatively safe and has well-defined effects (like setting it for the
read command, as in
IFS= read -r line and
IFS=, read -r field1 field2 field3), but trying to understand its behavior in general is, in my opinion, more work than it's worth. Also, if you do change it, either isolate it to a particular command by doing the assignment as a prefix to the command (again, as in
IFS= read -r line) or by setting it back to normal as soon as possible after whatever you need to change it for.
Now to the question: these aren't good examples of
IFS effects, first because
$* expands to the current argument list, and interactive shells don't generally have arguments, so it's going to expand to the empty string. You can change that with the
set command if you want. Here's an example:
$ echo "$*"
$ set -- "foo bar" "baz/quux"
$ echo "$*"
foo bar baz/quux
Second, because changing
IFS as a prefix to a particular command (as in
IFS= echo "$*") only affects the command as it runs, not while the shell is expanding its arguments (which happens before the command itself runs), and
echo itself isn't affected by
IFS (it always sticks its arguments together with spaces, no matter what
IFS is set to). For example:
$ IFS= echo "$*" # No effect, because IFS is only set for echo, which ignores it
foo bar baz/quux
Contrast that with setting
IFS for the shell itself:
$ saveIFS=$IFS # Save the normal IFS, so we can set it back later
$ IFS= # Set IFS for the entire shell
$ echo "$*" # Now we'll see an effect
$ IFS='+-*/' # Let's try another value
$ echo "$*" # Now the arguments get merged, first char of IFS beween them
$ echo $* # See below
foo bar baz quux
$ printf '%s\n' $* # See below
$ IFS=$saveIFS # Set it back to normal, to avoid trouble later
So what happened with
echo $* when
IFS was "+-*/"? Well,
IFS is used both to merge and split arguments, so just like with
echo "$*", the
$* bit expanded to
foo bar+baz/quux, but then since it wasn't double-quoted it then immediately got split into words (using all of the characters in
IFS), so it got split into three arguments to
echo: "foo bar" "baz", and "quux", and
echo then stuck those all together with spaces in between. Essentially the same thing happens with the
printf command, except the format string makes it print each following argument on a separate line, so you can see that "foo bar" is just one argument.
BTW, some people use the
saveIFS approach like I used here, some prefer to
unset IFS afterward, which makes the shell act as if
IFS was back to its normal space-tab-newline value. Both work, but not together. If you
unset IFS, and then later try to save & restore it, it'll come out set to the empty string, and things will be weird. You could also explicitly reset it with
IFS=$' \t\n', but that's not portable to all shells (and will cause really weird effects in shells that don't support
$' '). Sigh.
EDIT: See this question for more options & discussion of how to save & restore the value of
BTW2, in most situations you don't want the arguments either merged or split, so what you want is
$@ doesn't merge the arguments, and with double-quotes it doesn't split them either (or expand them as filename wildcards) -- it just passes them straight through. But don't use
args="$@", because that actually does merge them like
"$*" (or maybe with " " instead of the first char of
IFS, depending on the shell) (it has to merge them to save them in a plain variable). Use
args=("$@") instead, to save them as an array.