假设我们有一个目录,其中包含三个文件:file_1
,file_2
和非常不方便命名的file 3
。如果我对filename expansion的理解是正确的,则bash
解释字符串的方式
echo *
是因为它看到了(未加引号的)*
,并修改了字符串,使其现在可以读取
echo file_1 file_2 file 3
然后,由于没有更多的扩展要执行,bash尝试评估字符串。在这种情况下,它将运行命令echo
,并向其传递四个参数:file
,3
,file_1
和{{1} }。无论如何,输出是相同的:
file_2
但是,在其他情况下,似乎并非如此。例如
$ echo *
> file 3 file_1 file_2
$ echo file 3 file_1 file_2
> file 3 file_1 file_2
但是,如果shell扩展按in the bash
documentation所述的方式工作,则它们应该是相同的。
在$ arr1=( * )
$ arr2=( file 3 file_1 file_2 )
$ echo ${#arr1}
> 3
$ echo ${#arr2}
> 4
循环中类似的情况发生:
for
我想念什么?在这种情况下不会发生通气吗?
根据MIT's Hacker Tools的建议,我正在整理一个GitHub存储库以集中我的点文件。我正在编写的脚本有两种用法:
$ for f in *; do echo $f; done
> file 3
> file_1
> file_2
$ for f in file 3 file_1 file_2; do echo $f; done
> file
> 3
> file_1
> file_2
在第一种情况下,./install.sh DOTFILE [DOTFILE [DOTFILE ...]]
./install.sh -a
中的每个命名点文件都被符号链接到我的主目录中的对应点文件;在第二个中,src/config
标志提示脚本运行,就像我已经输入每个点文件作为参数一样。
我想出的解决方案是使用两个数组之一-a
和ln -sih
在for
循环中运行$@
。 1 因此,只需分配*
或FILES=( $@ )
,然后运行FILES=( * )
-在我看来,for f in $FILES
应该在此分配中中断,如果文件名带有里面的空间。显然*
比我聪明,因为它没有,但是我不明白为什么。
bash
子句排除。
答案 0 :(得分:3)
从您链接到的bash
documentation:
扩展顺序为:大括号扩展;波浪线扩展 参数和变量扩展,算术扩展和命令 替换(以从左到右的方式完成);分词和 文件名扩展。
文件名扩展发生在 分词之后,因此,扩展的文件名本身不再需要进一步的分词。