zsh 中的 IFS 行为与 bash 不同

Vio*_*rel 6 bash zsh

foo() {
    local lines=$(ls -l)
    local IFS=$'\n'
    for line in $lines; do
        echo $line
    done
}
Run Code Online (Sandbox Code Playgroud)

在 zsh 中,循环只执行一次,因为ls -lcommand的输出不会被新行拆分,并且整个文本块都被传递到 $line 中。但在 bash 中,按预期工作。如何在两个 shell 中具有完全相同的行为?

我不是在寻找循环“ls”输出的替代解决方案。只是想了解为什么它在 zsh 中不起作用,但在 bash 中却可以正常工作。代替“ls”命令可以是其他任何东西。例如“ps -a”。行为是一样的。输出不是按行分割的。

谢谢!

Dom*_*nik 5

默认情况下,ZSH 不拆分单词(与其他 shell 一样):

foo() {
    local lines=$(ls -l)

    local IFS=$'\n'
    if [ $ZSH_VERSION ]; then
      setopt sh_word_split
    fi

    for line in $lines; do
        echo line: $line
    done
}

foo
Run Code Online (Sandbox Code Playgroud)

感谢@chris-johnsen的回答。我支持他更好地使用数组的论点(在可能的情况下):

local lines=("$(ls -l)")
Run Code Online (Sandbox Code Playgroud)

其他选项是(仅限 ZSH):

  • local lines=("${(f)$(ls -l)}"),哪里(f)是简写(ps:\n:)
  • for line in ${=lines}; do (注意添加的等号)