为什么文件 glob 不受分词的影响?

the*_*fog 3 bash wildcards

我们建议,在 bash 脚本中,我们不应该解析 ls 的输出

上面链接的网页推荐的代码如下:

# Good!
for f in *; do
    [[ -e $f ]] || continue
    ...
done
Run Code Online (Sandbox Code Playgroud)

或用文件名填充数组

myfiles=( ~/* )
Run Code Online (Sandbox Code Playgroud)

但是当我查看这些示例并了解 bourne shell 通常如何处理未加引号的字符串时,我的感觉是,如果我在包含空格的文件名上使用此代码,则 glob 会爆炸文件上的每个 - 空格分隔 - 单词。例如,如果我有以下目录

$ ls -1  
a file I downloaded from the net.pdf
apple.sh
hello world.txt
Run Code Online (Sandbox Code Playgroud)

我运行这个

for file in *
    do printf "%s\n" "$file"
done
Run Code Online (Sandbox Code Playgroud)

我期待未引用的字符串行为。例如

a
file
I
downloaded
from
the
net.pdf
apple
hello
world
Run Code Online (Sandbox Code Playgroud)

但我得到的是正确的行为

a file I downloaded from the net.pdf
apple
hello world
Run Code Online (Sandbox Code Playgroud)

数组类似

myfiles=( * )
declare -p myfiles
declare -a myfiles='([0]="a file I downloaded from the net.pdf" [1]="apple" [2]="hello world")'
Run Code Online (Sandbox Code Playgroud)

我的问题是这是为什么?
是不是因为 glob 扩展是在分词后完成的?(以便这些类型的文件操作产生正确的输出?)

Mik*_*kel 8

文件名扩展发生在分词后

https://www.gnu.org/software/bash/manual/html_node/Shell-Expansions.html#Shell-Expansions

展开的顺序是:大括号展开;波浪号扩展、参数和变量扩展、算术扩展和命令替换(以从左到右的方式完成);分词;和文件名扩展。