zsh 对变量内容进行迭代的奇怪行为

zsh 对变量内容进行迭代的奇怪行为

当我使用 ZSH 迭代变量内容时,我遇到了奇怪的行为。在这种情况下,演示比长篇大论要好,所以我的问题如下:

(yoann@freya) test_bash » ls
file1  file2  file3
(yoann@freya) test_bash » for f in $(ls); do echo $f-SUF; done
file1-SUF
file2-SUF
file3-SUF
(yoann@freya) test_bash » files=$(ls); for f in $files; do echo $f-SUF; done 
file1
file2
file3-SUF
(yoann@freya) test_bash »

我希望第二次迭代的结果与第一次迭代的结果相同。我尝试了以下方法:

  • 其他人的 ZSH(同一发行版):运行良好
  • 在我的计算机上使用 bash:工作正常
  • 删除我的.zshrc:问题仍然存在。
  • 如果我做

    文件=$(ls); 对于 $(echo $files | tr '\n' ' ') 中的 f; 执行 echo $f-SUF; 完成

它工作正常。但是再一次,如果我捕获 tr 上管道的 echo 的结果,最后我只得到一个 -SUF。

我真的不知道发生了什么,有人知道吗?

谢谢。

一些信息:

  • 发行版:debian Wheezy
  • zsh 版本:zsh 4.3.17(x86_64-unknown-linux-gnu)

如果有任何用处:

(yoann@freya) test_bash » locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.utf8"
LC_NUMERIC="en_US.utf8"
LC_TIME="en_US.utf8"
LC_COLLATE="en_US.utf8"
LC_MONETARY="en_US.utf8"
LC_MESSAGES="en_US.utf8"
LC_PAPER="en_US.utf8"
LC_NAME="en_US.utf8"
LC_ADDRESS="en_US.utf8"
LC_TELEPHONE="en_US.utf8"
LC_MEASUREMENT="en_US.utf8"
LC_IDENTIFICATION="en_US.utf8"
LC_ALL=en_US.utf8

答案1

首先,它是一个解析输出的坏主意ls. 请使用通配符(参见文件名生成man zshexpn),就你的情况而言

for f in *; do
  echo ${f}-SUP
done

您的两个示例似乎在 bash 中都可以工作(只要文件名等中没有空格)的原因是,bash 默认使用空格来拆分参数,而实际上zsh并非如此。您zsh也可以使用此选项在 中获得此行为:

setopt SH_WORD_SPLIT

解释来自man zshoptions

字分割导致对未加引号的参数扩展执行字段拆分。请注意,此选项与单词拆分无关。(请参阅“参数扩展”部分。)

但请认真对待上述链接中给出的建议!

相关内容