Consider the following shell script, which I intend to run on any POSIX.1-2004 compatible shell.
log() { echo debug: "$*" } A=foo:bar:baz IFS=: for i in $A do log token ">> >>" "$i" done unset IFS
I want to iterate over values separated by colons. Inside the loop, I want to call a log function, which should be able to discard all the arguments passed to it intact, with several spaces in each argument stored. When I run this code, this is the result that I get.
debug: token:>> >>:foo debug: token:>> >>:bar debug: token:>> >>:baz
It’s good that the two spaces in ">> >>" were saved due to the use of "$*" , i.e. quotes for the asterisk special parameter, as defined in Section 2.5.2 POSIX.1-2004 Special Parameters .
But the bad thing is that as a result of the same use, the three arguments passed to log are now separated by a colon ( IFS ).
I will solve this problem on unset ting IFS in a for loop.
log() { echo debug: "$*" } A=foo:bar:baz IFS=: for i in $A do unset IFS log token ">> >>" "$i" done unset IFS
Now the result is what I want.
debug: token >> >> foo debug: token >> >> bar debug: token >> >> baz
But I want to know if it is possible that in some POSIX shell, canceling IFS inside a for loop can have the side effect of changing IFS for a for loop while it is in progress?
For example, I'm worried that some POSIX shells might print the following output for my second code sample.
debug: token >> >> foo debug: token >> >> bar:baz
Can someone tell me, referring to the appropriate sections from POSIX.1-2004 , if my second code example is safe, and if it is guaranteed to create the same behavior in all POSIX-compatible shells?
If my second code example is unsafe, then I may have to agree to something like this that does not change IFS .
log() { echo debug: "$*" } A=foo:bar:baz echo "$A" | tr : "\n" | while read i do log token ">> >>" "$i" done