不。 glob 扩展的上下文与普通的命令扩展上下文基本相同,其中所有扩展都被处理,生成的单词以不可变的方式保存以进行迭代。for-in 循环没有惰性迭代器。当然,扩展可能会产生副作用并与 glob 混合,因此必须热切地评估它们。这就是为什么find -exec [+;]
在可以同时做事情的情况下仍然如此频繁地推荐使用 globstar。
关于这个 4096 问题,我真的无话可说。我觉得这两者真的没有可比性。Shell for..in 只是扩展单词并迭代它们。
一个相关的常见问题解答是您是否可以执行诸如提前读取要分配的下一个值之类的操作。据我所知,没有类似 bourne 的 shell 可以额外访问单词列表。您必须为此使用数组。基本上所有的限制for..in
都可以通过数组来克服。
这是我为 Bash 编写的一个有趣的惰性 coproc 生成器。这很没用。
coproc x { while :; do find . -type f -maxdepth 1 -exec sh -c 'read; echo "$1"' -- {} \;; done; };
while :; do
echo 1 >&"${x[1]}"
read -ru "${x[0]}" file
echo "$file"
sleep 1
done
还有一个for..in
与问题无关的花絮——在 ksh93 和 Bash 的 git devel 分支中,可以以一种有趣的方式使用“控制变量”。
function f {
nameref x # Chet may decide not to emulate the typeset -n aliases
for x; do
x=hi
done
}
typeset -a arr
f 'arr['{0..3}']'
typeset -p arr # arr=(hi hi hi hi)
每次迭代都会将给定对象的引用分配给 x。当然,在 ksh 中,它可以是任意复杂的数据类型。我想这可能会被滥用以某种方式模拟懒惰。不幸的是,这种模式似乎不适用于 mksh。
编辑忘记写这篇文章后,我发现很多 shell 实际上优化了for x
语法。我假设至少是写时复制,并且仅在循环中使用或for x in
时复制位置参数。shift
set