我们建议,在 bash 脚本中,我们不应该解析 ls 的输出
上面链接的网页推荐如下代码:
# Good!
for f in *; do
[[ -e $f ]] || continue
...
done
或用文件名填充数组
myfiles=( ~/* )
但是,当我查看这些示例并了解 bourne shell 通常如何处理未引用的字符串时,我的感觉是,如果我在包含空格的文件名上使用此代码,则 glob 会在文件上的每个 - 空格分隔 - 单词上爆炸。例如,如果我有以下目录
$ ls -1
a file I downloaded from the net.pdf
apple.sh
hello world.txt
我运行这个
for file in *
do printf "%s\n" "$file"
done
我期待未引用的字符串行为。例如
a
file
I
downloaded
from
the
net.pdf
apple
hello
world
但我得到的是正确的行为
a file I downloaded from the net.pdf
apple
hello world
类似的数组
myfiles=( * )
declare -p myfiles
declare -a myfiles='([0]="a file I downloaded from the net.pdf" [1]="apple" [2]="hello world")'
我的问题是为什么会这样?
是因为分词后进行了全局扩展吗?(以便这些类型的文件操作产生正确的输出?)
分词后发生文件名扩展
https://www.gnu.org/software/bash/manual/html_node/Shell-Expansions.html#Shell-Expansions
[[ -e $f ]]
是一个特例。[[
是保留字;之间[[
和]]
不同的规则是有效的。其中之一是不执行分词。