6

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?

fpmurphy
  • 2,464
  • 1
  • 18
  • 22
Lone Learner
  • 18,088
  • 20
  • 102
  • 200
  • 1
    Yes, zsh is knowingly and intentionally in violation here. That said, relying on string-splitting isn't a good practice in *any* shell -- even in bash, I'd encourage you to use `read -r -a args <<<"$1"` or such to read into an array, then `for arg in "${args[@]}"; do ...` – Charles Duffy Sep 20 '17 at 21:22
  • 2
    This is a case where `zsh` does what POSIX *should* do, it POSIX hadn't been burdened with maintaining existing behavior as much as possible. As the worst possible solution, you could use `setopt SH_WORD_SPLIT` to restore the POSIX behavior. – chepner Sep 24 '17 at 14:14

2 Answers2

3

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.

hchbaw
  • 4,894
  • 18
  • 16
2

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.)

Micah Elliott
  • 9,600
  • 5
  • 51
  • 54
  • I felt quite ok writing shell command scripts using Ruby... and then I tried to learn more Bash and Zsh,,, but they seem like Martian language to me – nonopolarity Dec 08 '20 at 04:16