为什么在zsh中执行read -a失败

21

如果我输入:

echo "1 the
dquote> 2 quick
dquote> 3 brown" | while read -a D; do echo "${D[1]}--${D[0]}"; done

在bash中它说:

the--1
quick--2
brown--3

但在zsh中它说:

zsh: bad option: -a

为什么?我应该做些什么呢?

1个回答

27

在两种shell中,read都是一个内置命令。它们具有相同的目的,但实现和选项略有不同。

为了在zsh中读取一个数组,read需要使用选项-A(而不是-a):

echo "1 the
2 quick   
3 brown" | while read -A D; do echo $D[2]--$D[1]; done 
注意: zshbash 之间还有许多其他区别:
  • zsh 默认从一开始编号数组,而 bash 从零开始。
  • echo $ARRAY 输出在 zsh 中为所有元素,而在 bash 中只输出第一个元素。
  • 要在 sh 中打印数组的第三个元素,可以使用 echo $ARRAY[3]。在 bash 中需要使用大括号来限定下标,且第三个元素的下标为 2: echo ${ARRAY[2]}
  • zsh 中通常不需要引用参数扩展以正确处理带空格的值。例如:
FILENAME="no such file"
cat $FILENAME

zsh 中只会打印一条错误信息:

cat: 'no such file': No such file or directory

但在 bash 中有三个错误信息:

cat: no: No such file or directory
cat: such: No such file or directory
cat: file: No such file or directory
  • zsh中,默认情况下内置的echo会解析转义码。而在bash中,则需要传递-e参数来实现此功能。

  • echo 'foo\tbar'
    

    zsh

    foo     bar
    

    bash:

    foo\tbar
    
  • 一般来说,需要记住的是,虽然 zshbash 相似,但它们并不完全相同。


    1
    嗯,它似乎没有将“-a”用于其他任何功能。看起来是一种奇怪而毫无意义的不兼容性。 - Adrian May
    3
    两种shell都不旨在与另一种shell兼容,它们都试图遵循POSIX标准,但是-a-A对于read命令的POSIX变种来说都不是选项。我猜测zsh使用-A是为了与其set内置命令保持一致,后者也使用-A来设置数组。顺便提一下:实际情况恰恰相反;bash(1996年的2.0版本)没有跟随zsh(1994年的2.5版本)的例子使用-A,这是很奇怪的,因为它没有将-A用于任何其他用途。 ;) - Adaephon
    我认为当没有任何不利因素时,zsh会尝试与bash兼容。zsh可能是第一个,但bash更受欢迎,使用率高达数千倍。zsh没有将“-a”用于其他任何事情,所以我认为它应该采取务实的做法。1996年已经过去20年了。 - Adrian May
    就像我写的那样:bashzsh非常不同,期望它们相同只会带来问题。改变一个选项并不会改变这一点。而且,为什么zsh要打破已经建立的行为,只是为了更像bash呢?如果你想要bash结构,请使用bash。如果你想要可移植的代码,请使用符合POSIX标准的结构。如果你想利用zsh的功能,你需要使用zsh结构,其中许多结构与bash中的结构或多或少不同。 - Adaephon

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接