![zsh 对变量内容进行迭代的奇怪行为](https://linux22.com/image/1376658/zsh%20%E5%AF%B9%E5%8F%98%E9%87%8F%E5%86%85%E5%AE%B9%E8%BF%9B%E8%A1%8C%E8%BF%AD%E4%BB%A3%E7%9A%84%E5%A5%87%E6%80%AA%E8%A1%8C%E4%B8%BA.png)
当我使用 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
字分割导致对未加引号的参数扩展执行字段拆分。请注意,此选项与单词拆分无关。(请参阅“参数扩展”部分。)
但请认真对待上述链接中给出的建议!