简体   繁体   中英

zsh is not splitting by IFS after parameter expansion

This is my code to loop over colon separated values and do something with each value.

f()
{
    IFS=:
    for arg in $1
    do
        echo arg: $arg
    done
}

f foo:bar:baz

This works fine in most POSIX compliant shells.

$ dash foo.sh
arg: foo
arg: bar
arg: baz
$ bash foo.sh
arg: foo
arg: bar
arg: baz
$ ksh foo.sh
arg: foo
arg: bar
arg: baz
$ posh foo.sh
arg: foo
arg: bar
arg: baz
$ yash foo.sh
arg: foo
arg: bar
arg: baz

But it does not work as expected in zsh.

$ zsh foo.sh
arg: foo:bar:baz

Is zsh in violation of POSIX here?

Yes. Zsh has chosen its own way.

Here is the zsh faq entry: “3.1: Why does $var where var="foo bar" not do what I expect?”

In this particular case, you could workaround by adding the -y option to the zsh invocation:

$ zsh -y foo.sh
arg: foo
arg: bar
arg: baz

You could take a look at the zsh's faq especially the chapter 2 and 3. The more you've experienced other shells, the more you can find zsh's pitfalls.

In Zsh it is usually cleaner to split with the provided (s) flag (vs using IFS ). A solution for your data would then be:

% f() { for e in ${(s.:.)1}; print $e }
% f foo:bar:baz
foo
bar
baz

See the PARAMETER EXPANSION section in zshexpn(1) man page for more details and related flags.

(I assume you mean colon -separated values.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM